题目:输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。

解法一:

按字母个数依次打印。

public static void main(String[] args){
        combine("ABC");
}
/**
 * 法一:按照个数依次调用combination递归打印,
 * @param str
 */
public static void combine(String str) {
    if (str == null)
        return;
    int length = str.length();
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < length; i++) {
        combination(str, 0, i, sb);
    }
}

/**
 * 法一:递归打印
 * @param str
 * @param index
 * @param number
 * @param sb
 */
public static void combination(String str, int index, int number, StringBuilder sb){
    if (number == -1 ) {
        System.out.println(sb.toString());
        return;
    }
    if (index == str.length())
        return;
    sb.append(str.charAt(index));

    combination(str, index + 1, number - 1, sb);

    sb.deleteCharAt(sb.length() - 1);

    combination(str, index + 1, number, sb);
}

解法二:笛卡尔乘积算法

所以不管多少个字母
你只要将1-2^n-1的连续自然数转换成2进制
就可以匹配出来所有的组合了。
注意:AB和BA是一样,AC和CA是一样,BC和CB是一样的,ABC,ACB,CBA,CAB,BAC,BCA都是一样的

解题思路:

n个字母,有2的n次方减1个组合
所以你可以用二进制数来表示对应的字母
比如说abc
设置a=1,b=10,c=100则

001=a
010=b
100=c
011=ab
101=ac
110=bc
111=abc

PS:想到bitmap。

/**
 * 方法二:用二进制标识每一个字符串
 * @param str
 */
void print(String str) {
    //组合的个数
    int length = (2 << (str.length()-1)) - 1;
    for (int j = 1; j <= length ; j++) {
        StringBuffer sb = new StringBuffer();
        int tempLen = j;
        int i = 0 ;
        while (tempLen > 0) {
            if ((tempLen & 1) == 1) {
                sb.append(str.charAt(i));
            }
            tempLen = tempLen >> 1;
            i++;
        }
        System.out.println(sb);
    }
}

你可能感兴趣的:(算法)