posts - 48,comments - 156,trackbacks - 0
          先來復習一下概率論的基礎知識:
          n 個數,從中取 m 個進行進行排列,有多少中排法。
          如果不同位置可以重復:
          第 1 個位置有 n 種選法
          第 2 個位置有 n 種選法
          ......
          第 m 個位置有 n 種選法
          根據乘法原理:總共 n**m 種排法

          如果不能重復
          第 1 個位置有 n 種選法
          第 2 個位置有 n-1 種選法
          ......
          第 m 個位置有 n-m+1 種選法
          根據乘法原理:
          總共 n*(n-1)*....*(n-m+1)種排法
          全排列就是 n! 種排法


          如果我們要編程生成所有的排列,基本上都是嵌套循環

          假如 list 有 n 個元素,從中選 2 個進行排列,偽代碼基本如下

          for i=0 to list.length-1
              
          for j=0 to list.length-1{
                  
          //找到一種排列方法
                  temp=list[i,j]

                  
          //根據情況排除重復
                  ..
              }

          問題是上面的例子,我們知道選 2 個元素排列,所以循環是 2 層。
          但是,如果我們求得是 P(list,n),n 并不確定,我們不知道循環是幾層,要想寫一個通用的函數,只能借鑒上面的思想,但是不能使用上面的形式

          我的想法是:
          1、用一個數組 repeat[] 來保存每層的循環變量:repeat[0] 保存第 0 層循環變量的位置,repeat[1] 保存第 1 層循環變量的位置......repeat[n-1] 保存第 n-1 層循環變量的位置
          2、標記當前正在第幾層循環:layer
          3、集合長度已知 :size = list.length
          4、臨時數組:temp[],長度為 n 
          3、算法描述如下:
          循環體(layer == 0 且 repeat[0]== size  則退出循環)
          {
                如果(前 n-1 層)
                {
                      取出該層循環變量:pos=repeat[layer]
                      如果 (pos 到達該層末尾,即 pos==size)
                      {
                            temp[layer]=null
                            repeat[layer]=0//該層循環變量歸零
                            layer--//回到上一層
                            continue
                      }
                      否則
                      {
                            temp[layer]=list[pos]
                            repeat_count[layer]++//該層循環變量增加1
                            layer++//層數增加 1
                            continue
                      }
                否則(在最內層)
                {
                      不停改變 temp 最后一個元素,每改變一次,就得到一種新的組合,該層循環變量增加1
                      當最內層也到達 List 末尾:將該層循環變量歸零,回到上層
                }

          下面是我用 Python 編寫的 permutation 函數,接受三個參數
          第一個參數:如果數字則返回排列數;如果是集合,則返回排列的集合
          第二個參數:選幾個數排列,默認全排序
          第三個參數:是否允許重復,默認不允許
          例子:
          print permutation(10),'\n'   #全排列數
          print permutation(10,2),'\n' #10 選 2 排列數
          print permutation(10,duplicate=True),'\n'  #允許重復的全排列
              
          li
          =['a','b','c']
          print '全排列:',permutation(li),'\n'
          print '選2 :',permutation(li,2),'\n'
          print '允許重復 :',permutation(li,duplicate=True),'\n'

          運行結果:


          下面給出源代碼:
          排列

          //==========================================
          posted on 2009-07-29 00:49 左洸 閱讀(1798) 評論(2)  編輯  收藏 所屬分類: 數據結構與算法

          FeedBack:
          # re: 求一組序列的全排列[未登錄]
          2009-07-29 20:27 | lanxiazhi
          hello,以下是遞歸java實現:
          class Perm
          {
          static String letters="123456";//任意不重復字符串
          static int count;
          static void per(StringBuilder sb)
          {
          if(sb.length()==letters.length())
          {
          System.out.println(sb);
          count++;
          return;
          }
          for(int i=0;i<sb.length()+1;i++)
          {
          per(sb.insert(i,letters.charAt(sb.length())));
          sb.deleteCharAt(i);
          }
          }
          public static void main(String[] args)
          {
          per(new StringBuilder());
          System.out.println(count);
          }
          }
            回復  更多評論
            
          # re: 求一組序列的全排列
          2009-07-31 00:07 | ecbeta
          -module(lib_misc).
          -export([perms/1]).
          perms([]) -> [[]];
          perms(L) -> [[H|T] || H <-L, T<-perms(L--[H])].


          初學erlang. 書上的一個demo. 全排序. 真TMD簡單  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 四川省| 建阳市| 徐汇区| 巨鹿县| 京山县| 海林市| 仁化县| 甘谷县| 应城市| 尉氏县| 沅江市| 德保县| 泸西县| 沙田区| 天水市| 伊通| 富川| 华池县| 旺苍县| 汝南县| 诸暨市| 平顺县| 独山县| 庆安县| 镇宁| 汝南县| 嘉黎县| 肇州县| 固原市| 铜陵市| 慈利县| 昌宁县| 南郑县| 万荣县| 蚌埠市| 广昌县| 栖霞市| 正安县| 宾阳县| 漳州市| 萍乡市|