質問: 2つ文字列が与えられます。1つ目は見本で、2つ目は、見本とは形が少し違うものです。2つ目の文字列を1つ目の文字列と同じにしたいのですが、左から右へしか動かすことはできないというルールがあります。例えば、abcをcabに直したいときは、abc->bca->cabとしなければなりません。そして最後に、最短で何回動かしたかを出力するのが目的となっています。以下のコードは、思考中だった時の失敗コードなのですが、2点だけわからないところがあります。 その内容は、 1.出力結果は4つ出てくると考えるのですが、結果は3つなのはなぜか。 2.出力されるtotalの最後が1と出力されるのは、なぜか。 です。 ![また、下記に私の考えを図にした写真を添付しました。](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/15ceb03a0b6c500b0531bf41521c572c.jpeg) ``` r=[5, "APPLE", "LEAPP"] #左から、文字数、見本の文字、修正する文字 です。 num=int(r[0]) total=0!イメージ説明 model=[] target=[] for i in range(num): model.append(r[1][i]) target.append(r[2][i]) def sorten(total): for i in range(num): #print(total) #print(target) if model[i]!=target[i]: moji=target[0] target.pop(0) target.append(moji) #print(target) total+=1 sorten(total) print(total) sorten(total) ```
回答: 関数の中で、その関数それ自身を呼び出すことを「再帰」といいます。 そこで、最初の「sorten」の呼出しを「再帰前のsorten」と、その中での「sorten」の呼出しを「再帰1回目のsorten」などと呼んで説明していきます。 1 再帰前のsorten 最初の`for` で、`i` は `0` です。 `target`は`['L', 'E', 'A', 'P', 'P']` です。 `model[0]` は`A`で、`target[0]`は`L`なので、`if`のボディの部分が実行されます。 その結果、`target`は`['E', 'A', 'P', 'P', 'L']`に、`total`は`1`になって、「再帰1回目のsorten」に突入します。 2 再帰1回目のsorten `i`は`0`で、`target[0]`は`E`です。`A`ではないので、`if`のボディが実行されます。 その結果、`target`は`['A', 'P', 'P', 'L', 'E']`に、`total`は`2`になって、「再起2回目のsorten」に突入です。 3 再帰2回目のsorten `i`は`0`で、`target[0]`は`A`なので、`if`のボディは実行されず、`sorten`の最後の行の`print(total)`がようやく実行されます。 `total`は`2`だったので、`2`が表示され、「再帰2回目のsorten」は終了します。 そして、中断していた「再帰1回目のsorten」の続きを行います。 4 再帰1回目のsortenの続き `i`が`1`になって、`for`のボディを実行します。 `target`は`['A', 'P', 'P', 'L', 'E']`なので、`target[1]`は`P`です。 `model[1]`も`P`なので、`if`のボディは実行されず、`print(total)`が実行されます。 「再帰1回目のsorten」の中で、`total`は`2`になっていたので、`2`が表示され、「再帰1回目のsorten」は終了します。 そして、中断していた「再帰前のsorten」を再開します。 5 再帰前のsortenの続き `i`が`1`になって、`for`のボディを実行しますが、`target`は`['A', 'P', 'P', 'L', 'E']`なので、`if`のボディは実行されず、`sorten`最後の行の`print(total)`が実行されます。 「再帰1回目のsorten」に突入するときの`totsl`は`1`でしたから、ここでは`1`が表示され、「再帰前のsorten」も終了します。 `sorten`の仮引数である`total`はローカルな変数なので、関数の途中で中断して再起に突入した場合、再帰の中で`total`の数が増えても、中断したところに戻って再開したら、`total`の値は、中断前の値で再開されるのです。 グローバルな`target`との違いです。 6 まとめ 以上から、出力の数は3つで、最後の出力は1になります。