随笔 - 16  文章 - 42  trackbacks - 0
<2007年12月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

失业中…

常用链接

留言簿(7)

随笔档案(16)

技术Blog

搜索

  •  

最新随笔

最新评论

阅读排行榜

评论排行榜

全排列算法的递归与非递归实现.出于语言特性问题,运行效率较低.
< script language = " JavaScript " >
<!--
// 全排列递归算法
//
code by meixx(梅雪香)
/*
递归的算法采用分而治之的思想 
考虑序列 P1P2P3Pn 可以分解为 P1 + C(P2P3Pn),依此类推.
*/

function  combination(arr) {
    
var  len  =  arr.length;
    
if (len  ==   2 ) {
        
var  a  =  arr[ 0 ], b  =  arr[ 1 ];
        
return  [a + b,b + a];
    }

    
else   if (len  ==   1 )   return  arr;
    
else {
        
var  strRtn  =   "" ;
        
for ( var  i = 0 ;i < len;i ++ ) {
            strRtn 
+=  merge(arr[i],combination(arr.slice( 0 ,i).concat(arr.slice(i + 1 ,len)))).join( " , " ) + " , " ;
        }

        
return  strRtn.replace( / \,$ / , "" ).split( " , " );
    }

}

function  merge(head,arr) {
    
for ( var  i = 0 ;i < arr.length;i ++ )
        arr[i] 
=  head  +  arr[i];
    
return  arr;
}

/*
var ar = combination("54321".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 =  A1A2A3An ( Ai!=Aj , (1<=i<=n  , 1<=j<=n, i != j  ) )
找到P的一个最小排列Pmin = P1P2P3Pn  有  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.交换后, P1P2P3Pn  并不是准确的后一个排列。因为根据第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;
            
return  ar.slice( 0 ,i).concat(ar.slice(i).reverse());
        }

    }

    
return   null // 找不到"不符合趋势"的数字,说明所有的排列已经找到
}

/*
var ar = Combin("f4e3r21".split(""));
for(var i=0;i<ar.length;i++)
    document.write(ar[i].join(""),"<br>");
*/

// -->
</ script >

posted on 2006-10-21 12:15 梅雪香 阅读(11201) 评论(8)  编辑  收藏

FeedBack:
# re: 全排列算法的递归与非递归实现 2007-09-11 17:05 roadtang
做的很漂亮. 学习.  回复  更多评论
  
# re: 全排列算法的递归与非递归实现 2007-09-11 17:08 roadtang
还有, 愿楼主早日找工作, 楼主失业一定是哪个公司的损失  回复  更多评论
  
# re: 全排列算法的递归与非递归实现 2007-12-08 18:12 yisoutong
朋友,请问你的函数如何修改呢

我要从字符串"1,2,3,4,5"中取出任意对字符来重新排列

比如:

'取任意2个重新排列
1,2
1,3
1,4

2,1 '去掉重复的
2,3
2,4

3,1 '去掉重复的
3,2
3,4

4,1 '去掉重复的
4,2 '去掉重复的
4,3'去掉重复的

  回复  更多评论
  
# re: 全排列算法的递归与非递归实现 2007-12-08 18:18 yisoutong
朋友,请问你的函数如何修改呢

我要从字符串"1,2,3,4"中取出任意对字符来重新排列

比如:

'取任意2个重新排列
1,2
1,3
1,4

2,1 '去掉重复的
2,3
2,4

3,1 '去掉重复的
3,2
3,4

4,1 '去掉重复的
4,2 '去掉重复的
4,3'去掉重复的


  回复  更多评论
  
# re: 全排列算法的递归与非递归实现 2007-12-10 12:14 梅雪香
没有看明白你的意思  回复  更多评论
  
# re: 全排列算法的递归与非递归实现 2007-12-11 21:48 void
..........太垃圾了..竟然还要用IF&&这么冗余..  回复  更多评论
  
# re: 全排列算法的递归与非递归实现[未登录] 2008-09-18 17:32 null
谢谢。
找了好些网页。你这个讲的最清楚。  回复  更多评论
  
# re: 全排列算法的递归与非递归实现 2009-05-22 09:11 美元
不错还可以!  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: