- 爱易网页
-
JavaSript
- 求js计算排列组合算法,该怎么解决
日期:2014-05-16 浏览次数:20425 次
求js计算排列组合算法
字符串:A,2,3,4,5
需要得到:
A234
A235
A245
A345
2345
这样的结果,用js如何算,字符串可扩展到n个
------解决方案--------------------
<script>
var str= "A,2,3,4,5,6 ";
var strArray=str.split( ", ");
var len=strArray.length;
var newArray=new Array();
for(var i=0;i <len-3;i++){
for(var j=i+1;j <len-2;j++){
for(var k=j+1;k <len-1;k++){
for(var l=k+1;l <len;l++){
newArray.push(strArray[i]+strArray[j]+strArray[k]+strArray[l]);
}
}
}
}
alert(newArray);
</script>
------解决方案--------------------
<script language= "JavaScript ">
<!--
//全排列递归算法
//code by meixx(梅雪香)
/*
递归的算法采用分而治之的思想
考虑序列 P1P2P3...Pn 可以分解为 P1 + C(P2P3...Pn),依此类推.
*/
function combination(arr){
var len = arr.length;
if(len == 0) return [];
if(len == 2){
var a = arr[0], b = arr[1];
return [[a,b],[b,a]];
}
else if(len == 1) return [[arr[0]]];
else{
var arRtn = [];
for(var i=0;i <len;i++){
arRtn = arRtn.concat( merge( arr[i],combination(arr.slice(0,i).concat(arr.slice(i+1,len))) ) );
}
return arRtn;
}
}
function merge(head,arr){
for(var i=0;i <arr.length;i++)
arr[i].unshift(head);
return arr;
}
/*
var ar = combination( "7654321 ".split( " "));
for(var i=0;i <ar.length;i++)
document.write(ar[i].join( " "), " <br> ");
*/
//-->
</script>
<script language= "JavaScript ">
<!--
//全排列非递归算法
//code by meixx(梅雪香)
/*
非递归全排列算法的基本思想是:
1.找到所有排列中最小的一个排列P.
2.找到刚刚好比P大比其它都小的排列Q,
3.循环执行第二步,直到找到一个最大的排列,算法结束.
下面用数学的方法描述:
给定已知序列 P = A1A2A3...An ( Ai!=Aj , (1 <=i <=n , 1 <=j <=n, i != j ) )
找到P的一个最小排列Pmin = P1P2P3...Pn 有 Pi > P(i-1) (1 < i <= n)
从Pmin开始,总是目前得到的最大的排列为输入,得到下一个排列.
方法为:
1.从低位到高位(从后向前),找出“不符合趋势”的数字。即找到一个Pi,使Pi < P(i+1)。
若找不到这样的pi,说明我们已经找到最后一个全排列,可以返回了。
2.在 P(i+1)P(i+2)...Pn 中,找到一个Pj,使得 Pj "刚刚好大于 "Pi.
( "刚刚好大于 "的意思是:在 P(i+1)P(i+2)...Pn 中所有大于Pi的元素构成的集合中最小的元素.)
3.交换 Pi , Pj 的位置.注意:此处不改变i和j的值,改变的是Pi和Pj.
4.交换后, P1P2P3...Pn 并不是准确的后一个排列。因为根据第1步的查找,我们有P(i+1) > P(i+2) > .... > Pn
即使进行了Pi和Pj的交换,这仍然是这一部分最大的一个排列。将此排列逆序倒置(变成最小的排列)即为所求的下一个排列.
5.重复步骤1-4,直到步骤1中找不到“不符合趋势”的数字.
*/
//参数arr:待进行全排列的数组(没有重复的元素)
function Combin(arr){
var arResult = [];
var ar = arr.sort();
arResult.push(ar);
for(;;){
ar = FindNext(arResult[0],ar);
if(!ar) return arResult;
arResult.push(ar);
}
}
function FindNext(arFirst,arLast){
for(var i=arLast.length-1;i> 0;i--){
if(arLast[i-1] < arLast[i]){ //找到了 "不符合趋势 "的数字
var ar = arLast.slice();
var strTail = ar.slice(i).join( " ");
var tmpStr = arFirst.join( " ");
var strSearch = tmpStr.substr( tmpStr.indexOf(ar[i-1]) + 1 );
//确定ar[i-1]要交换的字符及该字符的位置
for(var j=0,k=strSearch.length;j <k;j++){
var ch = strSearch.charAt(j);
var idx = strTail.indexOf(ch);
if( idx > = 0 ) break;
}
ar[i + idx] = ar[i-1];
ar[i-1] = ch;