全排列
字符串全排列问题,如[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,取哪些位置的组合。