1

順列の目的でジェネレーターを作成しようとしています。Pythonでそれを行う方法は他にもあることは知っていますが、これは別の方法です。残念ながら、私は価値を生み出すことができません。手伝ってくれますか?

def perm(s,p=0,ii=0):
    l=len(s)
    s=list(s)
    if(l==1):       
        print ''.join(s)
    elif((l-p)==2):
        yield ''.join(s)
        yield ''.join([''.join(s[:-2]),s[-1],s[-2]])
    else:
        for i in range(p,l):
            tmp=s[p]
            s[p]=s[i]
            s[i]=tmp        
            perm(s,p+1,ii)
4

2 に答える 2

5

あなたの行perm(s,p+1,ii)は本当に何もしません: それはタイプするのと同じです

>>> perm("fred")
<generator object perm at 0xb72b9cd4>

ただし、その呼び出しから譲歩した場合、つまり

        for subperm in perm(s, p+1, ii):
            yield subperm

それからあなたは得るでしょう

>>> list(perm("abc"))
['abc', 'acb', 'bac', 'bca', 'cab', 'cba']
>>> list(perm("abcd"))
['abcd', 'abdc', 'acbd', 'acdb', 'adbc', 'adcb', 'bacd', 'badc', 'bcad', 'bcda', 'bdac', 'bdca', 'cabd', 'cadb', 'cbad', 'cbda', 'cdab', 'cdba', 'dabc', 'dacb', 'dbac', 'dbca', 'dcab', 'dcba']

>>> len(_)
24
>>> len(set(perm("abcd")))
24

これは問題ないようです。それ以上のコードはテストしていません。

s[i]ところで、とs[p]を入れ替えることができますs[i], s[p] = s[p], s[i]tmp変数は必要ありません。

PS: 現在、1 文字のケースは処理していません。

于 2012-08-28T19:03:16.393 に答える
0

ジェネレーターでは、値を返したいときはいつでもyield。これは、次のような再帰的な階乗関数を持っているようです。

>>> def fact(n, result=1):
    if n==0: return result
    fact(n-1, result*n)

そして、なぜそれが何も返さないのか疑問に思います:

>>> fact(5)
>>>

その理由は、関数が再帰的に呼び出されても、値が失われるためです。あなたがしたいと思うでしょう:

>>> def fact(n, result=1):
    if n==0: return result
    return fact(n-1, result*n)

>>> fact(5)
120

同様に、アルゴリズムの再帰部分では、次のことを行います。

    for i in range(p,l):
        tmp=s[p]
        s[p]=s[i]
        s[i]=tmp        
        perm(s,p+1,ii)

yieldただし、これは何も行わないため、perm(s,p+1,ii)呼び出しからの値は返されません(編集:実際には、値は計算されません)。再帰呼び出しの結果を繰り返し処理し、それぞれを順番に返す必要があります。

    for i in range(p,l):
        tmp=s[p]
        s[p]=s[i]
        s[i]=tmp        
        for result in perm(s,p+1,ii):
            yield result
于 2012-08-28T19:13:49.557 に答える