2

簡単に検索しましたが、問題を解決するものは見つかりませんでした。

最初の 5 つの数字を取得して製品を調達するプログラムを作成しようとしています。その製品がこれまでに見つかった最大のものである場合は、そのように設定されます。

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

string = str(integer)

x = 0
largest = 0
stringlength = len(string)

while x < stringlength:
    a = int(string[x])
    b = int(string[x+1])
    c = int(string[x+2])
    d = int(string[x+3])
    e = int(string[x+4])
    if (a*b*c*d*e > largest):
        largest = a*b*c*d*e
        print(largest)
    x += 1

print(largest)

整数値自体は除外しましたが、参考までに 1000 桁です。このコードを実行しようとするたびに、「IndexError: string index out of range」が表示されます。誰でも助けることができますか?

4

2 に答える 2

7
string = str(integer)

x = 0
largest = 0
stringlength = len(string)

while x < stringlength-4: # going to -5 would be out of rangue
    a = int(string[x])
    b = int(string[x+1])
    c = int(string[x+2])
    d = int(string[x+3])
    e = int(string[x+4])
    if (a*b*c*d*e > largest):
        largest = a*b*c*d*e
        print(largest)
    x += 1

print(largest)
于 2013-06-18T22:04:29.963 に答える
2

これは、典型的な1 つずつずれているエラー(または、この場合は 4 ずつずれているエラー) です。

x達しstringlength-4たときx+4stringlength、 の終わりを過ぎた ですstringx < stringlength-4したがって、ではなくが必要ですx < stringlength

しかし、より高いレベルの抽象化を使用するようにコードを書き直して、これらの問題に遭遇しにくく、考えやすくすることを検討することをお勧めします。


まず、これの代わりに:

x= 0
while x < stringlength:
    # ...
    x += 1

これを行うだけです:

for x in range(stringlength):

次に、これで問題を解決できます。

for x in range(stringlength-4):

しかし、それをさらに進めましょう。


文字列をスライスすると、次のようにはなりませんIndexError:

for x in range(len(stringlength)):
    a, b, c, d, e = map(int, string[x:x+4])

ただし、これValueErrorで、開梱時に が得られます。しかし実際には、ここで 5 つの個別の変数に展開する必要はありません。シーケンスを維持して乗算するだけです。reduce(これはループで行うことができますが、私の意見では、これはPython で何かを記述する最も読みやすい方法である数少ないケースの 1 つです。)

for x in range(len(stringlength)):
    values = map(int, string[x:x+4])
    prod = reduce(operator.mul, values)
    if prod > largest:
        largest = prod
        print(largest)

これでエラーはなくなりましたが、これは最後の 4、3、2、および 1 の数値を掛け合わせているためです。そして、それがまさに問題です。そこで何が起こるべきかを決して決めていません。

これで、決定を明確にすることができます。それらをバッチとしてカウントしますか、それともスキップしますか?

さらに先に進みたい場合は、次のように動作するバージョン(ウィンドウの右端がリストの最後から外れると停止する)、次のitertoolsように動作するバージョン(次の場合にのみ停止する) を使用して、スライディング ウィンドウ グループ化関数を記述できます。ウィンドウの左端が消える):zipzip_longest

def groupwise(iterable, n):
    groups = itertools.tee(iterable, n)
    for i, group in enumerate(groups):
        next(itertools.islice(group, i, i), None)
    return zip(*groups)

def groupwise_longest(iterable, n, fillvalue=None):
    groups = itertools.tee(iterable, n)
    for i, group in enumerate(groups):
        next(itertools.islice(group, i, i), None)
    return itertools.zip_longest(*groups, fillvalue=fillvalue)

今、あなたはこれを行うことができます:

for group_of_five in groupwise_longest(string, 5, 1):
    values = map(int, group)
    prod = reduce(operator.mul, values)
    if prod > largest:
        largest = prod
        print(largest)

次に、最後に不完全なグループを比較したくない場合は、最初の行を次のように変更します。

for group_of_five in groupwise(string, 5):

for次に、すべての作業をループの外に移動できます。

groups = groupwise_longest(string, 5, 1)
intgroups = (map(int, group) for group in groups)
prods = (reduce(operator.mul, group) for group in groups)

これで一連の積が得られたので、最も高いものを見つけるには次のようにすればよいことは明らかです。

print(max(prods))

例えば:

>>> string = '12345678987654321'
>>> groups = groupwise(string, 5)
>>> intgroups = (map(int, group) for group in groups)
>>> prods = (reduce(operator.mul, group) for group in groups)
>>> max(prods)
28224

また、off-by-one エラーやその他の「小さな」エラーが発生する場所はどこにもないことに注意してください。もちろん、何か完全に間違っているか、書き方がわからないだけかもしれませんが、少なくともエラーは明らかな大きなエラーになり、デバッグが容易になります。

于 2013-06-18T22:17:33.470 に答える