O (n) zaman / uzay karmaşıklığı için, püf noktası her bir sonraki işlem için karmaları değerlendirmektir. Diziyi düşünün b
:
[b1 b2 b3 ... bn]
Horner yöntemini kullanarak , her bir takip için olası tüm karmaları değerlendirebilirsiniz. Bir taban değeri seçin B
(her iki dizinizdeki herhangi bir değerden daha büyük):
from b1 to b1 = b1 * B^1
from b1 to b2 = b1 * B^1 + b2 * B^2
from b1 to b3 = b1 * B^1 + b2 * B^2 + b3 * B^3
...
from b1 to bn = b1 * B^1 + b2 * B^2 + b3 * B^3 + ... + bn * B^n
Her sekansı, önceki sekansın sonucunu kullanarak O (1) zamanında değerlendirebildiğinizi, dolayısıyla tüm iş masraflarını O (n) değerlendirebileceğinizi unutmayın.
Şimdi bir diziniz var Hb = [h(b1), h(b2), ... , h(bn)]
, burası Hb[i]
hash b1
olana kadar bi
.
Dizi için aynı şeyi yapın a
, ancak küçük bir hile ile:
from an to an = (an * B^1)
from an-1 to an = (an-1 * B^1) + (an * B^2)
from an-2 to an = (an-2 * B^1) + (an-1 * B^2) + (an * B^3)
...
from a1 to an = (a1 * B^1) + (a2 * B^2) + (a3 * B^3) + ... + (an * B^n)
Bir diziden diğerine adım attığınızda, önceki dizinin tamamını B ile çarptığınızı ve yeni değeri B ile çarptığınızı not etmelisiniz. Örneğin:
from an to an = (an * B^1)
for the next sequence, multiply the previous by B: (an * B^1) * B = (an * B^2)
now sum with the new value multiplied by B: (an-1 * B^1) + (an * B^2)
hence:
from an-1 to an = (an-1 * B^1) + (an * B^2)
Şimdi bir diziniz var Ha = [h(an), h(an-1), ... , h(a1)]
, burası Ha[i]
hash ai
olana kadar an
.
Şimdi, n'den 1'e kadar Ha[d] == Hb[d]
tüm d
değerleri karşılaştırabilirsiniz , eğer eşleşirse, cevabınız vardır.
DİKKAT : Bu bir karma yöntemdir, değerler büyük olabilir ve hızlı bir üs alma yöntemi ve modüler aritmetik kullanmanız gerekebilir, bu da size (neredeyse) çarpışmalar verebilir , bu yöntemi tamamen güvenli hale getirmez. İyi bir uygulama, B
gerçekten büyük bir asal sayı olarak bir taban seçmektir (en azından dizilerinizdeki en büyük değerden daha büyük). Ayrıca, her adımda sayıların sınırları taşabileceğinden de dikkatli olmalısınız, bu nedenle K
her işlemde ( modulo ) kullanmanız gerekir (burada K
asal daha büyük olabilir B
).
Bu, iki farklı sekansın aynı hash'a sahip olabileceği , ancak iki eşit sekansın her zaman aynı hash'a sahip olacağı anlamına gelir .
b[1] to b[d]
ve sonraa
eşleşirse dizi hesaplama karma değerine gidin,a[1] to a[d]
o zaman bu sizin cevabınızdır, eğer hesaplanan karma değerinia[2] to a[d+1]
yeniden kullanarak hesaplama karma değeri değilsea[1] to a[d]
. Ama dizideki nesnelerin, üzerinde bir haddeleme karma hesaplamak için uygun olup olmadığını bilmiyorum.