2010-11-02 61 views
9

如何生成列表b(1,6,8,3,9,5)的所有可能排列,包括不同長度的排列?例如:生成所有長度的所有排列

List a = [1,2,3] 
generateperms(a) 
1,2,3 
3,1,2 
3,2,1 
1,3,2 
2,1,3 
2,3,1 
2,3 
1,2 
1,3 
2,1 
3,2 
3,1 

等等,並獲得每個長度的所有permutarions?

編輯: 我只是要利用這一點,用Python編寫的,作品不夠好:

import itertools 
a = ['a','b','c'] 
for i in range(len(a)): 
    print list(itertools.permutations(a,i+1)) 
+0

這功課嗎?如果是這樣,請給它加上標籤,並考慮發佈一些有關迄今爲止取得的進展。 – bcat 2010-11-02 04:56:18

+2

這不是家庭作業,對不起說或張貼其他明智抱歉。 – 2010-11-02 11:44:04

回答

5

我認爲這將是每個子集的所有排列組合。

返回子集的最簡單方法是從0(空集)到輸入列表(完整集)的長度考慮所有二進制整數。因此,您計數從0到包括2**(length(input)),並使用結果來屏蔽從特定子集中排除的所有元素。

從那裏你應該能夠使用任何在'網絡返回排列的代碼的例子。

+0

順便提一句,在Python中,itertools模塊具有生成排列的功能,並且我創建了一個醜陋的單行程序來使用生成器表達式返回所有子集。然而,在這裏發帖太可怕了。 – 2010-11-03 06:51:25

2

我建議先從簡單的東西。假設l是包含n元素的列表。首先,你可以寫一個函數來生成所有具有固定長度的排列組合k?那麼,你可以找到一種方法,用不同的k值重複調用該函數,以生成長度爲0的排列,長度爲1的所有排列,長度爲2的所有排列,等等,直到你到達n

0

一般而言,長度爲n的列表有n!安排或排列。所以有多個長度,我們會有n!(n-k)!其中k是0 < k < n。

+0

請不要發佈完整的代碼作爲家庭作業/面試問題的問題,而是提供有關指導的建議。 – Yuliy 2010-11-02 05:16:13

+0

我很抱歉,我沒有看到它被標記爲家庭作業。 – Jim 2010-11-02 05:22:07

1

考慮生成一個字符串的所有排列的遞歸實現。如果在構建它們時存儲子排列,那麼您將擁有所有你想要的排列。

二郎,作爲出發點(這是3.3 Permutations修改後的版本)

perms([]) -> [[]]; 
perms(L) -> 
    [ [H|T] || H <- L, T <- perms(L -- [H])] 
    ++ [ [T] || H <- L, T <- perms(L -- [H]) ]. 

但請注意,這讓你有重複和大量空數組的數組,你就必須要去除使輸出更漂亮。

1

早些時候我提到我在Python中編造了一個可怕的lambda表達式,用於在2.6中添加二進制字符串內置函數,使用bin()整數生成序列的所有子集。

下面是它的醜陋版本:

subsets = lambda s: (
    (s[x] for x,c in 
     enumerate("0" * (len(s)-len(bin(i)[2:])) + bin(i)[2:]) 
     if int(c)) 
    for i in range(0,2**len(s) 
    ) 
) 

但我注意到,我可以用一個簡單的調用字符串的zfill()方法(感謝SO User: gimel)替換表達的"0" * ... +"部分。這樣就顯得稍微不太討厭的:

subsets = lambda s: (
     [s[x] for x,c in 
       enumerate(bin(i)[2:].zfill(len(s))) 
       if int(c) 
       ] 
     for i in range(0,2**len(s)) 
    ) 

這一點,儘管它的外觀,是一個相對簡單的實現什麼,我描述:給定一個表示從零到我們組的大小任意整數的二進制字符串,屏蔽掉所有的元素對應於我們的二進制字符串中的零。這是內部列表理解。外部(發生器)表達式僅包含必要的範圍。

OP的使用itertools.permutations()和兩個參數的方法更加優雅。如果我知道查看該函數的__doc__字符串,我可能會想到它。但是,我確實不得不花一點時間讓自己相信,兩種方法都可以得到相同的結果。