前例中,我们求了一个字符串的排列组合,其中再细分出一种情况,长度与原字符串长度相同的排列组合。

这里,我们只求组合,不要求“排列”。从数学的解集上看,本例的解集是上一例的子集。思路有所不同。

具体的方法是,先自己求简单的,比如abcde中长度为2的子串组合,然后用笔记录下自己输出的过程。发现如下:

1、问题可以化解为求某个字符串长度的K(K<=n)的子串组合,当K从1到n时,解集的集合即为所求

2、求某个字符串长度的K(K<=n)的子串组合,模拟人脑的思路是:比如求abcde中长度为3的子串组合:

    有三大类,分别是a,b,c开头,而且c开头正好是cde一种组合,d开头的没有啦。

    然后a开头的又可以化解为求“bcde”中长度为2的子串组合,发现可以递归。

    于是用笔,画出每个思路的路线图,归纳总结,可得出代码。虽然说是这么简单,但是我想了一整天,脑袋真是笨。中途还在想,自己是不是没有写代码的天赋呢?一度绝望中。

    但是后来上厕所,想想,也许吧,不算聪明,跟google那帮人绝对没法比,但是世界不仅需要决定聪明的人,也需要我们这一类平庸之辈啊,想想,还是自己开心就好,开心的时候,就是自己解答出来的时刻,感觉真好。

    如厕悟出的一个道理是,写程序,一定要严谨,像数学题一样,来不得一点马虎,否则就是南辕北辙,缘木求鱼。集中精力,很重要,特别是像我这种非绝顶聪明的人,一定不能天马行空,要踏踏实实,一步一步地把思路写出来,越清晰越靠谱,来不得一点儿天马行空。也许就是这一点点的差别,导致自己竟然耗费了一整天的时间,才在最后的时候,静下心来,瞬间解决出来了。感慨万千,一定要心静,才行!!!    

/**
 * 输入一个字符串,输出该字符串中字符的所有组合。
 * 举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。
*/
public class StringCombination {

private int len;

public void setLen(int i) {
this.len=i;
    }

/**
     * 求以start开头的,长度为wanted的子串
     * @param k:字符串数组
     * @param start:数组小标
     * @param wanted:所需子串的长度
     * @param pre:前缀
*/
public void getStringCombination(char[] k,int start,int wanted,String pre) {
if(wanted==0) {
        System.out.println(pre);
return;
    }

int last_index=len-wanted;
for(int i=start;i<=last_index;i++) {
// System.out.print(k[i]);
        getStringCombination(k, i+1, wanted-1,pre+k[i]);
// System.out.println("");
    }

    }

public void getRs(String content) {
//组合子串的长度从1到length
    for(int i=1;i<=content.length();i++) {
        getStringCombination(content.toCharArray(), 0, i,"");
    }
    }

public static void main(String[] args) {
    StringCombination sCombination=new StringCombination();
        Scanner scanner=new Scanner(System.in);
        System.out.println("please input :");
        String content=scanner.nextLine();
        sCombination.setLen(content.length());
        sCombination.getRs(content);
    }

}