今天拿出我那本几年前买的冶工版的算法书翻了半天.组合算法那章发现只讲了排列算法和幂集算法
(这类问题的解法基本没下过功夫,临时拿来补一下).囧...那这章为啥要叫"组合问题算法"?
最后自己按照类似书上所写排列算法的decrease-by-one的思路弄出了一个.思路如图:
假设有集合A的元素包含0 1 2 3,在其中任取3个不重复的元素组成一个组合
则可表示为这样三棵树:
对应组合:
013
012
023
123
其中每个由根结点到其叶子节点的路径所经过的节点即是一个组合.第三棵树由于找不
到所需的节点而终止.树的问题很容易可以转换成一个递归解决.文字描述啥的俺不太擅
长,直接上代码:
function print (m){ WScript.Echo (m); } //求排列数 function a (n,m){ if (m == 0) return 1; if (m>n) return 0; var ret = n; for (var i =1;i<=(m-1);++i){ ret*=n-i; } return ret; } //组合数 function c (n,m){ return a(n,m)/a(m,m); } //求全排列 function permutation (n,handler){ } //求重复排列 function permutation2 (n,handler){ } //求组合 function cb (si,s,n,m,r,h){ r[si]=s;//填充位, if (si == m-1)//填充满了,调用回调函数 { h (r); return; } ++si; for (s=++s;s<n;++s){ cb (si,s,n,m,r,h);//递归填充下一位 } } //求组合 function combination (n,m,handler){ if (m>n) return; var result = new Array(); for (var i = 0;i<n-m+1;++i) cb (0,i,n,m,result,handler); } var nn = 4; var mm = 3; print ("总共" + c (nn,mm) + "种组合:"); combination (nn,mm,function (r){ var str = ""; for (var i = 0;i<r.length;++i){ str += r[i]+" "; } print (str); });
使用cscript运行后输出:
总共4种组合:
0 1 2
0 1 3
0 2 3
1 2 3