java 组合_java 全组合 与全排列

一、全组合

public static voidCombination( ) {/*基本思路:求全组合,则假设原有元素n个,则最终组合结果是2^n个。原因是:

* 用位操作方法:假设元素原本有:a,b,c三个,则1表示取该元素,0表示不取。故去a则是001,取ab则是011.

* 所以一共三位,每个位上有两个选择0,1.所以是2^n个结果。

* 这些结果的位图值都是0,1,2....2^n。所以可以类似全真表一样,从值0到值2^n依次输出结果:即:

* 000,001,010,011,100,101,110,111 。对应输出组合结果为:

空,a, b ,ab,c,ac,bc,abc.

这个输出顺序刚好跟数字0~2^n结果递增顺序一样

取法的二进制数其实就是从0到2^n-1的十进制数

* ******************************************************************

* *

**/String[] str= {"a" , "b" ,"c"};int n = str.length; //元素个数。//求出位图全组合的结果个数:2^n

int nbit = 1<

System.out.println("全组合结果个数为:"+nbit);for(int i=0 ;i

System.out.print("组合数值 "+i + " 对应编码为: ");for(int j=0; j

int tmp = 1<

System.out.print(str[j]);

}

}

System.out.println();

}

}

运行流程:

举例:3个元素:a,b,c。所以有2^3=8个组合结果:所以i=0,1,2,....7.对应应输出 a,b,ab,c...abc (注意a表示001,不是100.)

将i变成2进制:

i=1 = 001    i=2 =010 i=3=011

(1)j=0 (1)j=0 (1)j=0

移1位: 1<

和i=001相与,两个位都为1,返回1 与i无相同位 和i=001相与,两个位都为1,返回1

输出:a 输出a

(2) j=1 (2) j=1 (2) j=1

再移一位: 1<

与i=001相与。无相同1 和i相与,两个位都为1,返回1 和i相与,两个位都为1,返回1

输出b 输出b

(3) j=2 3) j=2 (3) j=2

移一位 1<

与i无相同位 与i无相同位 与i无相同位

所以i=001, 只输出a. 所以i=010, 只输出b. 所以011,输出ab

*************************************

* 可见上面每一个数字i,只会判断判断3次,因为只需要移三次位,二进制就遍历完了

* *************************************

---------------------------------------------------------------------------------------------------------

另一个大同小异版本代码:

public static voidcombination1() {/*全组合:

* 思路是利用二进制的特性,每次加1即可遍历所有位的不同情况,很好理解

代码同上*/String arr[]= { "a", "b", "c"};int all =arr.length;int nbit = 1 <

StringBuffer sb= newStringBuffer();for (int j = 0; j < all; j++) {if ((i & (1 << j)) != 0) {

sb.append(arr[j]);

}

}

System.out.println(sb);

}

二、全排列

递归:

* 从集合中依次选出每一个元素,作为排列的第一个元素,然后对剩余的元素进行全排列,如此递归处理,

* 从而得到所有元素的全排列。以对字符串abc进行全排列为例,我们可以这么做:以abc为例:

* 固定a,求后面bc的排列:abc,acb,求好后,a和b交换,得到bac

* 固定b,求后面ac的排列:bac,bca,求好后,c放到第一位置,得到cba

* 固定c,求后面ba的排列:cba,cab。

*

* 即递归树:

str:   a      b      c

ab ac   ba bc     ca cb

result: abc acb   bac bca        cab cba

public static void permutation1(String str ,String result ,intlen){/*全排列 递归实现

递归树:

str: a b c

ab ac ba bc ca cb

result: abc acb bac bca cab cba*/

//结果 开始传入"" 空字符进入 len 是这个数的长度

if(result.length()==len){ //表示遍历完了一个全排列结果

System.out.println(result);

}else{for(int i=0;i

permutation1(str, result+str.charAt(i), len);

}

}

}

}

public static void main(String args[]) throwsException {

String s= "abc";

String result= "";

permutation1(s, result, s.length());}

递归另一种写法:或者采用July的方法:

从集合中依次选出每一个元素,作为排列的第一个元素,然后对剩余的元素进行全排列,如此递归处理,

* 从而得到所有元素的全排列。以对字符串abc进行全排列为例,我们可以这么做:以abc为例:

* 固定a,求后面bc的排列:abc,acb,求好后,a和b交换,得到bac

* 固定b,求后面ac的排列:bac,bca,求好后,c放到第一位置,得到cba

* 固定c,求后面ba的排列:cba,cab。

public static void permutation(String[] str , int first,intend) {//输出str[first..end]的所有排列方式

if(first == end) { //输出一个排列方式

for(int j=0; j<= end ;j++) {

System.out.print(str[j]);

}

System.out.println();

}for(int i = first; i <= end ; i++) {

swap(str, i, first);

permutation(str, first+1, end); //固定好当前一位,继续排列后面的

swap(str, i, first);

}

}private static void swap(String[] str, int i, intfirst) {

String tmp;

tmp=str[first];

str[first]=str[i];

str[i]=tmp;

}

·public static void main(String args[]) throwsException {String[] str= {"a","b","c"};

permutation(str,0, 2);//输出str[0..2]的所有排列方式

} }

参考http://blog.csdn.net/morewindows/article/details/7370155 总结:

1.全排列就是从第一个数字起每个数分别与它后面的数字交换。

2.去重的全排列就是从第一个数字起每个数 分别与它后面非重复出现的数字交换。

3.全排列的非递归就是由后向前找替换数和替换点,然后由后向前找第一个比替换数大的数与替换数交换,最后颠倒替换点后的所有数据。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值