6

次のように、*演算子を使用して、固定構造で任意の長さの文字列を作成できます。

length = 10
print "0" * length

これにより、期待されるものが返されます0000000000。この問題は、長さが長すぎる場合に発生し、オーバーフローエラーが発生します。

length = 10000000000000000000000000000000000000000000000
print "0" * length

これにより、がOverflowError: cannot fit 'long' into an index-sized integer

私は興味があります、そのような定式化はどういうわけか任意の長さのサイズに使用できますか?lengthまたは、未知であり、そのような大きな価値を帯びる可能性があるシナリオを処理する正しい方法は何ですか?

4

2 に答える 2

10

いいえ、どのプログラミング言語でも、例のような大きな文字列を作成することはできません。文字列には、各文字が含まれています。そして、10 46バイトは、誰もがこれまでに保存するよりもはるかに多くのデータである可能性が高いです。1兆のGoogleデータセンターを引き継ぐことができ(Googleに1 YiBのストレージがあると仮定すると、まだそうではありません。)、ディスク容量ははるかに少なく、RAMはもちろん、そのような文字列に必要なものです。 。

例のような巨大な文字列を格納するには、文字列全体を実際にメモリに格納せずに、繰り返し回数が格納される方法でstr処理する独自のようなクラスを作成する必要があります。__mul__明らかに、この文字列への変更を許可するとすぐに、この実装は非常に複雑になります。

于 2012-12-27T02:40:53.393 に答える
3

Pythonで文字列ジェネレータのようなものを書くことができます。例えば:

import sys

def stringWithArbitraryLength(stringLength):
    n = 0
    while n < stringLength:
        # pattern here
        if n % 2 == 0:
            yield "0"
        else:
            yield "1"
        n += 1

Infinity = float('inf')

# Usage 1: print the long string
# for c in stringWithArbitraryLength(Infinity):
#   sys.stdout.write(c)

# Usage 2: instantiate the long string
soLong = stringWithArbitraryLength(100000)  # output 01010101....
print ''.join(soLong)

# Usage 3: transform the long string
def transformString(longLongString):
    for c in longLongString:
        if c == "1":
            yield "X"
        else:
            yield c
soLong2 = stringWithArbitraryLength(100000)  # output 0X0X0X0X....
print ''.join(transformString(soLong2))

いくつかの制限があります。

  1. ランダムアクセスではなく、シーケンシャルアクセスのみを許可します。したがって、文字列をウォークスルーするにはforループを使用する必要があります。
  2. 各文字は、より大きなインデックスを持つ文字に依存することはできません。
  3. 長さが長いとインスタンス化が困難になります。ただし、インスタンス化後にランダムアクセスを実行できます。

多くの場合、文字列全体をインスタンス化する必要はありません。IOストリームを使用して入出力を行うことができるためです。そして、ジェネレータを使用して文字列を処理します。したがって、データの一部のみを処理するたびに。

長い、または無限に長い文字列についてもっと理解したい場合は、Haskellなどのいくつかの非厳密な関数型言語を学ぶことができます。表現を怠惰に評価します。インフィニティリスト/文字列は、これらの言語でよく使用されます。

于 2012-12-27T03:01:31.390 に答える