前例中,我们求了一个字符串的排列组合,其中再细分出一种情况,长度与原字符串长度相同的排列组合。
这里,我们只求组合,不要求“排列”。从数学的解集上看,本例的解集是上一例的子集。思路有所不同。
具体的方法是,先自己求简单的,比如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);
}
}