非常に長い文字列をキーとして使用されている場合Dictの中で検索する時の複雑さとは何ですか?

川:

私はのpython3の文書、dictのためにそのPythonの使用ハッシュテーブル()から読み取ります。だから、検索時間の複雑さは、最悪のケースとしてO(N)とO(1)でなければなりません。しかし、最近、私はコースを取ったとして、教師はあなたがキーとしてint型を使用する場合にのみそれが起こると言います。あなたがキーとして、長さLの文字列を使用する場合は、検索時間の複雑さはO(L)です。

私は彼の誠実さをテストするためのコードスニペットを書きます

import random
import string
from time import time
import matplotlib.pyplot as plt

def randomString(stringLength=10):
    """Generate a random string of fixed length """
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(stringLength))

def test(L):
    #L: int length of keys

    N = 1000 # number of keys
    d = dict()
    for i in range(N):
        d[randomString(L)] = None

    tic = time()
    for key in d.keys():
        d[key]
    toc = time() - tic

    tic = time()
    for key in d.keys():
        pass
    t_idle = time() - tic

    t_total = toc - t_idle
    return t_total

L = [i * 10000 for i in range(5, 15)]
ans = [test(l) for l in L]

plt.figure()
plt.plot(L, ans)
plt.show()

結果は非常に興味深いです。あなたが見ることができるように、x軸はキーとy軸として使用する文字列の長さは、辞書内のすべての1000個のキーを照会する合計時間です。

ここでは、画像の説明を入力します。

誰もがこの結果を説明できますか?

私に優しくしてください。あなたが見ることができるように、私はこの基本的な質問をするならば、その手段は、私はPythonのソースコードまたは同等に複雑なインサイダー文書を読み取る能力を持っていません。

kaya3:

辞書はハッシュテーブルで、ハッシュテーブルのキーを検索すると、キーのハッシュを計算する必要があるので、その後、辞書にキーを検索する時の複雑さは、ハッシュ関数の時間計算量より小さくすることはできません。

CPythonとの現在のバージョンでは、長さLの文字列は、それはあなたが特定の文字列オブジェクトことをハッシュ化されたのは初めてだし、場合のハッシュを計算するためにO(L)時間がかかり、その文字列オブジェクトのハッシュがある場合はO(1)時間既に(ハッシュが格納されているため)が計算され:

>>> from timeit import timeit
>>> s = 'b' * (10**9) # string of length 1 billion
>>> timeit(lambda: hash(s), number=1)
0.48574538500002973 # half a second
>>> timeit(lambda: hash(s), number=1)
5.301000044255488e-06 # 5 microseconds

ように、それはあなたが辞書でキーを調べる際にかかる時間もあります。

>>> s = 'c' * (10**9) # string of length 1 billion
>>> d = dict()
>>> timeit(lambda: s in d, number=1)
0.48521506899999167 # half a second
>>> timeit(lambda: s in d, number=1)
4.491000026973779e-06 # 5 microseconds

また、辞書にキーが見上げていないことに注意する必要がありますだけの場合には、ハッシュが一致する場合、それはまだあなたが見上げたキーが辞書に使用するキーと同じであることをテストする必要があります。そのハッシュでハッシュマッチングが偽陽性です。文字列のテストの平等は、最悪の場合にはO(L)時間がかかります。

>>> s1 = 'a'*(10**9)
>>> s2 = 'a'*(10**9)
>>> timeit(lambda: s1 == s2, number=1)
0.2006020820001595

だから、長さLのキーと長さnの辞書のために:

  • キーが辞書に存在しない、そのハッシュが既にキャッシュされている場合、それは、それが存在しないか確認するためにO(1)平均時間を要します。
  • キーが存在しないと、そのハッシュがキャッシュされていない場合、それがためにハッシュを計算するO(L)の平均時間を要します。
  • キーが存在する場合、それはなぜなら等価試験の、ハッシュニーズを計算するか否か存在を確認するためにO(L)の平均時間を要します。
  • すべてのハッシュ衝突した文字列は、すべての最後の場所を除いて同じである場合ので、最悪の場合には、常にO(NL)で、その後ゆっくりと平等のテストをn回行う必要があります。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=23824&siteId=1