1. 程式人生 > >利用字典序法生成組合數

利用字典序法生成組合數

在組合數學的這本書中,生成組合數字有很多中方法,比較常用的序數法,字典序法 本文采用字典序法,生成一堆組合數字,即C(n,r),從n個數字中取得r個,演算法完整的定義如下:

從{1,2,…,n}中取r-組合表示為C1C2…Cr,令C1<C2<…<Cr,其中有i ≤Ci≤(n-r+i), i=1,2,…,r 第一個組合為{1,2 ,…,r} 生成後序組合的規則 對C1C2…Cr從右到左掃描,找出第一個滿足Ci<(n-r+i)的i Ci<-Ci+1 Cj<-Cj-1+1 , j=i+1,i+2,…r

根據以上的演算法描述,寫出演算法:

class Solution():
    def dirgenerate(self, n, r):
        #利用字典序法生成組合
        l = [i for i in range(n+1)]
        C = [i for i in range(r+1)]
        print(C)
        n = len(l) - 1
        r = len(C) - 1
        ffi = 0  # 找到的i
        count = 1
        while True:
            for i in range( len(C) - 1 ,0,-1): 
                if C[i] < (n - r + i):
                    ffi = i
                    break

            if i == 1 and C[i] == (n - r + i):  
                print('共有',count,'項')
                return

            C[i] = C[i] + 1
            if ( i+1 <= r) and C[i+1] == (n - r + i + 1):
                pass
            else:
                count += 1
                print(C)
            for j in range(i+1,r+1):
                C[j] = C[j-1] + 1
                if j == r:
                    count += 1 
                    print(C)

if __name__ == '__main__':
    n = int(input('請輸入n:'))
    r = int(input('請輸入r:'))
    Solution().dirgenerate(n,r)

需要注意的是: 1.演算法直到產生c1=n-r+1,c2=n-r+2,...,cr=n結束,也就是說找不到ci != n-r+i 的項時結束

if i == 1 and C[i] == (n - r + i):  
        print('共有',count,'項')
        return

2.一個位數加完了之後,向前面找,並且加1,此次不輸出!對之後的每一位進行加的時候也不輸出

總結一下,演算法的思想:就是從右向前掃,找到一個不符合Ci<(n-r+i)的數,對其加1,如果找到的數的i,向前面進位,那麼即它後面的每一項都比前一項大1