问答题 如何输出字符串的所有组合
【正确答案】
【答案解析】问题描述:假设字符串中的所有字符都不重复,如何输出字符串的所有组合?例如,输入字符串“abc”,则输出a、b、c、ab、ac、bc、abc,共7种组合。
根据题意,如果字符串中有n个字符,根据排列组合的性质,此时一共需要输出2^n-1种组合。
最容易想到的方式是递归法,遍历字符串,每个字符只能取或不取。若取该字符,就把它放到结果字符串中,遍历完毕后,输出结果字符串。
程序代码如下:
public class Test{
public static void combineRecursiveImpl(char[]c, int begin, int len, StringBuffer sb){
if(len==0){
System.out.print(sb+"");
return;
}
if(begin==c.length){
return;
}
sb.append(c[begin]);
CombineRecursiveImpl(c, begin+1, len-1, sb);
sb.deleteCharAt(sb.length()-1);
CombineRecursiveImpl(c, begin+1, len, sb);
}
public static void main(String[]args){
String s="abc";
char[]c=s.toCharArray();
StringBuffer sb=new StringBuffer("");
int len=c.length;
for(int i=1; i<=len; i++){
CombineRecursiveImpl(c, 0, i, sb);
}
}
}
程序输出为:
a b c ab ac bc abc
采用递归法求解,当n的值不是很大时,不存在效率低下的问题,但当n比较大时,效率会变得很差,因为栈调用次数约为2^n,为了提高效率,考虑到本题的特性,可以构造一个长度为n的01字符串(或二进制数)表示输出结果中是否包含某个字符,例如,“001”表示输出结果中不含字符a、b,只含c,即输出结果为c,而“101”,表示输出结果为ac。原题就是要求输出“001”到“111”这2^n-1个组合对应的字符串。
程序代码如下:
public class Test{
public static void Combine(char[]c){
if(c==null)
return;
int len=c.length;
boolean used[]=new boolean[len];
char cache[]=new char[len];
int result=len;
while(true){
int index=0;
while(used[index]){
used[index]=false;
++result;
if(++index==len)
return;
}
used[index]=true;
cache[--result]=c[index];
System.out.print(new String(cache).substfing(result)+"");
}
}
public static void main(String[]args){
String s="abc";
char[]c=s.toCharArray();
Combine(c);
}
}
程序运行结果为:
a b ab c ac bc abc