2011-07-14 14 views
1

私はプログラマーだが、私はいくつかのC#PerlやPythonを行い、 はとにかく、私は、記号や文字のリストで、順列を生成するには、この再帰的なコードを見つけましたが、私はそれがどのように動作するかを見つけ出すことはできませんか?誰もそれを説明する気にすることができますか?この再帰的なpython関数の仕組みを理解するのに役立ちますか?

#!/usr/bin/env python 
#-*- coding:utf-8 -*- 

def generate(charlist,state,position): 
    for i in charlist: 
     state[position] = i 
     if position == (len(state)-1): 
      print "".join(state) 
     else: 
      generate(charlist,state,position+1) 

generate("1234567890qwertyuiopasdfghjklzxcvbnm",[None]*8,0) 

ここでは、すべての正しい間隔を使用したコードです。

+1

関数を返すことはありません。したがって、関数は正しく再帰しません。 –

+0

私たちは行く、それが完璧なことを確認し、コードも同様に動作します。あなたがジャコブと言ったことにマッチするタイトルも編集しました。 – TheEliteNoob

+1

@ Jakob Bowyer再帰関数は、それ自身を呼び出す関数です。 –

答えて

3

これはないは、順列を生成しません。これは、n次元のデカルト積を生成する。 (プロセスでは、それはまた、すべての順列を生成しますが、のみ順列を生成するためのアルゴリズムが異なるだろう。)

それは、それがどのように動作するかを説明するために少し難しいですが、あなたは小さな入力に対する出力を見れば、あなたは何が起こっているか見ることができます。 'abc'[None] * 3のための出力を考えてみましょう(私は真の発電機として機能するようにコードを修正):

>>> def generate(charlist,state,position): 
...  for i in charlist: 
...   state[position] = i 
...   if position == (len(state)-1): 
...    yield "".join(state) 
...   else: 
...    for j in generate(charlist,state,position+1): 
...     yield j 
... 
>>> print list(generate('abc', [None] * 3, 0)) 
['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc', 
'baa', 'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 
'caa', 'cab', 'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc'] 

あなたが見ることができるように、何が起こるかからpositionたびに(インクリメント、つまり最初に、generate通話自体3倍012)。 recursion-loopを実行するたびに、'a'が現在の位置に置かれ、stateリストの最後に達しているかどうかがテストされます。もしそうなら、それは結果をもたらし、ではありません。この場合

、それが起こる、position == 2。今度はforループが起動し、'b''c'state[2]に格納し、それぞれの状態を生成します。その後、関数は終了し、制御は呼び出し側に返されます(position == 1)。その後、呼び出し側はforループを継続します。 state[1] = 'b'を設定してからpositionstateリストの終わりになくなったので、それは再び自身を呼び出します...今度はposition == 2、forループはstate[2] == 'a''b''c'などとなります。あなたはpythonでデカルト積を計算したい場合はところで

は、ここでは、再帰的なアルゴリズムを解析するためにあなたの読者を必要としない良い方法です:

>>> import itertools 
>>> [''.join(c) for c in itertools.product('abc', 'abc', 'abc')] 
['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc', 
'baa', 'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 
'caa', 'cab', 'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc'] 

また

を行うことができます与えられた文字の組み合わせ(3番目の引数が非ゼロでない限り)
>>> [''.join(c) for c in itertools.product(*['abc'] * 3)] 
+0

ありがとうございます!これはとても役に立ちました! – TheEliteNoob

2

どのように動作するのかわかりません。

print charlist, state, position 

を、それは変数が各呼び出しで使用されているものを教えてくれます:ちょうどdef generate...後にこの行を置きます。

+0

うん、わかりました、それを試してみましょう。それは役に立ちましたが、私はそれがなぜ機能するのか、各行が何をするのかを考えようとしています。 – TheEliteNoob

1

機能は、すべての可能な出力します。

それは、入力として取ります

  1. 結合される文字のリストまたは文字列を、
  2. 長さが一度に組み合わせるべき文字数表しリスト、
  3. 数各組み合わせのいくつの文字を第2のリストからの対応する文字に置き換えるべきかを示す(それにより、可能な組み合わせの数が減少する)。第2引数は8つのNone値のリストである場合

[None] * 8 == [None, None, None, None, None, None, None, None]ため)、ゼロ以外の値に第三の引数を設定するTypeErrorを引き起こすであろう。

@ senderleさんの回答は、関数内で何が起こるかを説明しています。

これは、Pythonic以外のコードの例です。最初の視点からその目的を説明するのが難しいからです。