web-dev-qa-db-ja.com

Python(再帰的)の文字列のすべての順列

これで頭を蹴る必要があります。次の再帰関数を定義しています。

def perms(s):
  if(len(s)==1):
    return s

  res = ''
  for x in xrange(len(s)):

    res += s[x] + perms(s[0:x] + s[x+1:len(s)])

  return res + '\n'

perms( "abc")は現在以下を返します:

abccb
bacca
cabba

望ましい結果は

abc
acd
bac
bca
cab
cba

ここでどこが間違っているのですか?解決策を考え出すためにこれを別の方法で考えるにはどうすればよいですか?

注: itertools関数を知っています。私は自分の学習のために順列を再帰的に実装する方法を理解しようとしています。そのため、コードの何が問題になっているのか、そしてそれを解決するために別の考え方をする方法を誰かに指摘してもらいたいのです。ありがとう!

10
gnp210

そこに行きます(再帰的順列):

def Permute(string):
    if len(string) == 0:
        return ['']
    prevList = Permute(string[1:len(string)])
    nextList = []
    for i in range(0,len(prevList)):
        for j in range(0,len(string)):
            newString = prevList[i][0:j]+string[0]+prevList[i][j:len(string)-1]
            if newString not in nextList:
                nextList.append(newString)
    return nextList

すべての順列文字列のリストを取得するには、入力文字列を使用して上記の関数を呼び出すだけです。例えば、

stringList = Permute('abc')

改行文字で区切られたすべての順列文字列の単一の文字列を取得するには、その関数の出力で'\n'.joinを呼び出すだけです。例えば、

string = '\n'.join(Permute('abc'))

ちなみに、上記の2つのオプションのprintの結果は同じです。

14
barak manos

順列の結果はコレクション、たとえばリストになります。このように考えると、コードがよりクリーンになり、必要に応じて結果を1つの文字列に結合できます。簡単な例は

def perms(s):        
    if(len(s)==1): return [s]
    result=[]
    for i,v in enumerate(s):
        result += [v+p for p in perms(s[:i]+s[i+1:])]
    return result


perms('abc')

['abc', 'acb', 'bac', 'bca', 'cab', 'cba']


print('\n'.join(perms('abc')))

abc
acb
bac
bca
cab
cba
11
karakfa

コードは次のとおりです。

def fperms(elements):
    if len(elements)<=1:
        yield elements
    else:
        for p in fperms(elements[1:]):
            for i in range(len(elements)):
                yield p[:i]+elements[0:1]+p[i:]
1
apoorva R

効率についてはわかりませんが、これも機能するはずです。

def find_permutations(v):
    if len(v) > 1:
        for i in perms(v):
            nv = i[1:]
            for j in perms(nv):
                print(i[0] + j)
    else:
        print(v)


def perms(v):
    if not hasattr(perms, 'original'):
        perms.original = v
        perms.list = []
    nv = v[1:] + v[0]
    perms.list.append(nv)
    if perms.original == nv:
        l = perms.list
        del perms.original
        del perms.list
        return l
    return perms(nv)

find_permutations('abc')
0
Brent Douglas