-2

基本的に、ある人が私のコードを改善するのを手伝ってくれました。問題は、それがまだ完全に失望しており、機能しないことです。私がやりたいことは、 lenRecur.number をリセットして、他の文字列を使用して正しい答えを取得して、関数を再度使用できるようにすることです(大きすぎない答え)

問題は hasattr にあると思います。しかし、削除することはできません。削除すると、文字列の長さの計算機が機能しなくなるからです。

とにかく、関数の後に lenRecur.number = 0 を追加しても、まだ機能しません。

関数が「return」にヒットすると、それは完了です。「戻る」前にリセットすると0が返ってきて正解ではないので困っています。

def lenRecur(aStr):
    if not hasattr(lenRecur, 'number'):
        lenRecur.number = 0
    '''
    aStr: a string

    returns: int, the length of aStr
    '''
    if aStr == '':
        return lenRecur.number
    else:
        lenRecur.number += 1
        return lenRecur(aStr[:-1])

Ps私のプログラム(?)/スクリプト(?)の目標は、input()メソッドを使用せずに入力文字列の長さを測定することです。より原始的な手段を使用して、 length() メソッドを再作成しようとしています。

スクリプトにはさまざまな入力が必要になるため、リセットする必要があります。

4

3 に答える 3

3

再帰的な強度と長さの関数だけが必要な場合は、簡単です。

def len_recur(a_str):
    if not a_str:
        return 0
    else:
        return 1 + len_recur(a_str[1:])

もちろん、これは末尾再帰ではありませんが、Python は末尾再帰を最適化しないため、問題にはなりません。

そして、どうしても末尾再帰にしたい場合、またはPython での末尾再帰に関する Paul Butler のトリックを読んで試してみたい場合でも、アキュムレータを格納してそれを実行したくはありません。関数の属性として。ローカル関数を定義する通常のトリックを使用するだけです (または、必要に応じて変更可能なデフォルト パラメーターを使用します)。

def len_tail_recur(a_str):
    def tail(a_str, acc):
        if not a_str:
            return acc
        else:
            return tail(a_str[1:], acc+1)
    return tail(a_str, 0)

これを実際の末尾再帰関数に変換して 1001 要素のリストを爆破しないようにしたい場合、および上記の Paul Butler リンクを理解できない場合は、Get length of list in Python using recursionに対する私の回答を参照してください。この問題を正確に解決します。(その質問に対する別の回答では、N の代わりに log N の再帰呼び出しを使用して問題を解決する方法も示されています。これは、問題を回避する別の方法ですlist

そうは言っても、実装が間違った方法であっても、実際には問題なく機能します。(これまでのところ、私はあなたのコードを慣用的な Python のように見えるように PEP8 化してきました。ここからはそのままコピーして貼り付けますが、実際のコードは上記のようになります。)

def lenRecur(aStr):
    if not hasattr(lenRecur, 'number'):
        lenRecur.number = 0
    '''
    aStr: a string

    returns: int, the length of aStr
    '''
    if aStr == '':
        return lenRecur.number
    else:
        lenRecur.number += 1
        return lenRecur(aStr[:-1])

print lenRecur('abc')
lenRecur.number = 0
print lenRecur('abcd')

これは3、次に を出力し4ます。もちろん、関数の内部でも値が必要なため、関数の外部lenRecur.numberから設定する必要があります。しかし、同じ種類のラッパーでそれを解決できます:

def lenRecur(aStr):
    lenRecur.number = 0
    '''
    aStr: a string

    returns: int, the length of aStr
    '''
    def recur(aStr):
        if aStr == '':
            return lenRecur.number
        else:
            lenRecur.number += 1
            return recur(aStr[:-1])
    return recur(aStr)
于 2013-01-17T00:39:30.993 に答える
2

関数内で状態変数を使用する必要はありません。再帰的な長さ計算機を作成したい場合は、次のようにします

def lenRecur (aStr):
    if (aStr == ""):
        return 0
    else
        return lenRecur (aStr [:-1]) + 1

また、このスタイルにはエラー チェックなどはありませんが、再帰について学習する目的で問題なく動作することに注意してください。

于 2013-01-17T00:39:00.837 に答える
1

再帰を使用して長さ関数を実装して再帰を理解しようとしている場合は、次のようなものを使用できます。

#!python
def lenRecur(something, curlen=0):
    if something:
        return lenRecur(something[1:], curlen+1)
    else:
        return curlen

... これが特に優れたコードであると主張するつもりはありません。しかし、それはあらゆる種類のシーケンス (文字列、リスト、タプル) で動作するはずです...実行中の Python インスタンスで最大再帰制限を超えない限り、 [1:] スライス操作が機能するものなら何でも。

あなたの例では、 hasattr を使用して、関数のオブジェクトに「数値」属性を「モンキーパッチ」することにより、同様の概念を実装しようとしています。私の例では、変数を再帰呼び出しに渡す方法としてデフォルト パラメーターを使用しています。

したがって、最初の呼び出しでは、curlen はゼロです (これを「オプションの」追加の引数で呼び出すと、偽の結果が得られます)。その呼び出しから、関数は、元のシーケンス (文字列) の一部を切り取り (1 つ短くする)、オプションの (curlen) 引数をインクリメントして自身を呼び出します。最後に、文字列/シーケンスの長さはゼロであり、前の (再帰的な) 呼び出しのそれぞれからゼロが返されます。

これを達成するのは不十分な方法であり、末尾再帰の削除に関する議論の出発点になる可能性があります (Google で検索してください)。ただし、関数/オブジェクトにモンキーパッチを適用しなくても機能します。

于 2013-01-17T00:56:36.077 に答える