您的位置:首页 > 其它

关于组合问题的一种巧妙方法

2013-04-09 09:59 253 查看
在算法设计与分析里,组合排列(或者表面像排列组合)的问题很好的解决方法主要是回溯法,广度优先遍历法。

这里提供关于组合问题一种巧妙的解决办法。比如我们要从m个元素里取n个元素的所有组合。

我们用一个m位二进制数代表m个元素(一位代表一个元素)。取n个元素可以看做是这个m位二进制数中有n位的值为1.

一个m位二进制数可以代表2的m次方个值,(代表m个元素所有组合的情况)

/**

* 从m个数里取n个数的组合的个数,这里i并不是一个m位数,只是使用了i最右边的m位数

* 思路:

* @param m

* @param n

* @return

*/

public static int getCombinations(int m,int n){

int total=0;

for(long i=0l;i<Math.pow(2, m);++i){

int count=0;

//j=0表示右边第一位,j=1表示右边第二位,

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

//>>>无符号右移,左边填充0,i>>>j先运算,把我们要考核的哪一位移到最右边,然后与1进行&运算,即可知道我们考核的那一位的值。

if((i>>>j&1)==1){

++count;

}

if(count>n){

break;

}

}

if(count==n){

++total;

}

}

return total;

}

/* 取组合方法

* 参数: list ---- 原始集合

* 返回: 包含所有组合的集合

*/

public static List<List<Object>> getCombinations(List<Object> list) {

List<List<Object>> result = new ArrayList<List<Object>>();

long n = (long)Math.pow(2,list.size());

List<Object> combine;

for (long l=0L; l<n; l++) {

combine = new ArrayList<Object>();

for (int i=0; i<list.size(); i++) {

if ((l>>>i&1) == 1)

combine.add(list.get(i));

}

result.add(combine);

}

return result;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐