给定如下输入字符串:

AB[C[DA,BF,GAL],DB[NX,AQQ,AAN,B],F[H[GG,BAND]]]

返回字符串数组:

["ABCDA", "ABCBF", "ABCGAL", "ABDBNX", "ABDBAQQ", "ABDBAAN", "ABDBB", "ABFHGG"]

我能够合成一个部分解,但如果有多个[children],它就很难跟踪父 node .

另一个测试字符串:ZHLADAOR[R[G[45D[COI,EMA],Q5D[COI,EMA],U5D[COI,EMA],Y5D[COI,EMA]],HE5D[COI,EMA]],SG[A5D[COI,EMA],E5D[COI,EMA],I5D[COI,EMA]]]

func expandNestedString(str string) []string {
    var parts []string
    var currentPart []rune
    var openBrackets int
    var level int
    var bitsBeforeComma int
    var prevBitsBeforeComma int

    for _, char := range str {
        if char == '[' {
            openBrackets++
            level++
            prevBitsBeforeComma = bitsBeforeComma
            bitsBeforeComma = 0
        } else if char == ']' {
            openBrackets--

            if openBrackets == 0 {
                if level == 0 && len(currentPart) > 0 {
                    parts = append(parts, string(currentPart))
                }
                currentPart = []rune{}
                level--
            } else {
                parts = append(parts, string(currentPart))
                currentPart = currentPart[:len(currentPart)-(bitsBeforeComma+prevBitsBeforeComma)]
                bitsBeforeComma = 0
            }
        } else if char == ',' {
            parts = append(parts, string(currentPart))
            currentPart = currentPart[:len(currentPart)-bitsBeforeComma]
            bitsBeforeComma = 0
        } else {
            currentPart = append(currentPart, char)
            bitsBeforeComma++
        }
    }

    if len(currentPart) > 0 {
        parts = append(parts, string(currentPart))
    }

    return parts
}

推荐答案

一般来说,这类似乎需要对齐圆括号或跟踪以前字符的模式的问题可以通过递归很好地解决.以下是一个行之有效的解决方案

func expand(s []rune, idx int) ([][]rune, int) {
    var prefix []rune
    var result [][]rune
    for ; idx < len(s); idx++ {
        switch s[idx] {
        case '[':
            runes, lastIdx := expand(s, idx+1)
            for _, r := range runes {
                result = append(result, append(prefix, r...))
            }
            idx = lastIdx
            prefix = []rune{}
        case ']':
            if len(prefix) > 0 {
                result = append(result, prefix)
            }
            return result, idx
        case ',':
            if len(prefix) > 0 {
                result = append(result, prefix)
                prefix = []rune{}
            }
        default:
            prefix = append(prefix, s[idx])
        }
    }
    if len(prefix) > 0 {
        result = append(result, prefix)
    }
    return result, idx
}

func expandNestedString(s string) []string {
    runes, _ := expand([]rune(s), 0)
    var result []string
    for _, r := range runes {
        result = append(result, string(r))
    }
    return result
}

here个操场上

Go相关问答推荐

区分Terminal和Hook Zerolog Go中的错误级别日志(log)输出

在Go中根据命名空间/字符串生成UUID

有没有办法通过Go cmdline或IDE(IntelliJ)找出我的 struct 实现了什么接口?

即使HTTP服务器正在使用GO和Protobuf、SQL Server启动,请求也不返回结果

Hugo错误:没有为此项目配置现有内容目录

如何使用 AWS sdk 在 Go 中正确解组 PartiQL 查询的结果?

Golang Gorm Fiber - 如何将定义为别名的名称发送到索引模板?

未实现的 desc = 未知服务 pb.AuthService 我的简单身份验证服务器上出现错误

如何绕过深层 xml,没有嵌套循环?

Golang telegram 机器人

在 Windows 11 上运行 go mod tidy 时的 gitlab 权限问题

杜松子wine 和中间件

Gorm 在自定义字符串类型上返回 scanner 错误

golang yaml 马歇尔网址

从Go中的随机日期开始以天为单位获取时间

go:embed 文件扩展名模式

panic :拨号 tcp:在 172.22.64.1:53 上查找 bookstoreDB:没有这样的主机

Golang ACMEv2 HTTP-01 挑战不挑战服务器

GoLang 遍历 yaml 文件

如何访问 Go 模板中数组的第一个索引的值