输出字符串的所有子串

Go 语言打印输出字符串 abcd 的所有子串?

面对一道看起来非常简单的算法题,我粗略的想一下,应该使用两层 for 循环来处理。外层循环切片的起点,内层循环切片的终点,这样是不是就可以解决掉这个问题呢?除了空字符串以外,确实打印了所有的子串。这道题本身是想考察算法还是想考察切片的截取特性呢?

for i := 0; i < len("abcd"); i++ {
    for j := i; j < len("abcd"); j++ {
        fmt.Println("abcd"[i:j+1])
    }
}

可不可以不使用两层 for 循环,而是使用递归来处理呢。每一个字符都有包含和不包含的下一个字符的选项,比如,第0为可以是空,也可以是a,如果第0位是空,接下来的第1为可以是空,也可以是b,依此类推,就跟一个二叉树一样的感觉。但并不是每一路分支都符合要求,还需要将不符合要求的剔除出去。继续想下去,我已经不能好好思考了。

但如何将树结构的每一路都完整的打印输出呢,我画了半天,如果通过追加的方式,是不是就可以省略剔除不合理分支的那一步操作,首先向数组中插入a,然后就是一个符合条件的子集,然后,追加b,这时候 ab 作为一个符合条件的子集,同时,b可以选择不追加,单独一个子集,依此类推

a
b   b
c   c   c
d   d   d   d

按照列的视角看,a是一个子集,ab、abc、abcd都是一个子集,同理第二列,b、bc、bcd也是一个子集,梳理出了这些过程,代码上如何用递归实现呢?其实就是从 abcd 里面弹出一个元素,对剩余的元素进行递归。