实现字符串全排列

全排列

字符串全排列问题,如[abc]三个元素的数组,会有[abc,acb,bac,bca,cab,cba]六种排列方式,全排列的实现方式很多,这里选取一个简单的递归解决方法,代码简单,比较容易理解。

/**
* 全排列Java源码实现
* @param buf 待全排列字符串的数组
* @param start 起始位置
* @param end 需要全排列的字串的长度
* @return
*/
public List<String> perm(char[] buf, int start, int end){
    if(start == end){
        String result = "";
        for(int i=0 ; i<end ; i++){
            result += buf[i];
        }
        list.add(result);    
        result = "";
    }else{
        for(int i=start ; i<buf.length ; i++){
            char temp = buf[i];
            buf[i] = buf[start];
            buf[start] = temp;
                
            perm(buf, start+1, end);
                
            temp = buf[i];
            buf[i] = buf[start];
            buf[start] = temp;
        }
    }
    return list;
}

递归的原理通过交换的方式实现全排列,将第i个字母与第一个字母交换后,对其余的子数组递归全排列。

组合算法

组合算法是取出一个数组的所有子数组的组合,这个在搜索引擎中经常使用,切词再拼词。基本方式就是[abc]的组合方式有[a,b,c,ab,bc,ac,abc]六种组合方式,总计2^n-1种组合方式。这里组合的方式采用位运算的操作,比递归要简单。

public static List<String> perm2(char[] buf){
    for(int i=1 ; i<(1<<buf.length) ; i++){
        String result = "";
        for(int j=0 ; j<buf.length ; j++){
            //判断哪一位为1
            if((i & (1<<j)) != 0){
                result += buf[j];
            }
        }
        list.add(result);
    }
    return list;
}

1<<buf.length相当于2^buf.length,表示共有这么多种组合情况,其二进制上的1表示每种情况取哪些字母。i & (1<<j)表示实际哪一位为1,取哪些位置的组合。

原文地址:https://www.cnblogs.com/silianbo/p/4839887.html