ठीक है, यहां एक पागल विचार है।
एक ऐसा फ़ंक्शन बनाएं जो निर्धारित करता है कि ओ (एन) में लंबाई के आवर्ती सबस्ट्रिंग है (जहां एन टेक्स्ट की लंबाई है)। यह रोलिंग हैश का उपयोग करके किया जा सकता है (Rabin-Karp String Matching Algorithm के लिए विकिपीडिया देखें) रैखिक समय में सभी एन हैंश उत्पन्न करने के लिए और संबंधित सबस्ट्रिंग स्थितियों को संग्रहीत करने के लिए हैशटेबल/बीएसटी (या नक्शा या निर्देश या जो भी आपकी भाषा इसे कॉल करता है) का उपयोग करके किया जा सकता है। डेटा संरचना में वर्तमान हैश डालने से पहले, हम जांचते हैं कि हमने इसे पहले देखा है या नहीं।यदि यह पहले देखा गया है, तो हम केवल उन इंडेक्स को देखते हैं जहां यह हैश उत्पन्न हुआ था और देखें कि संबंधित सबस्ट्रिंग एक गैर-ओवरलैपिंग मैच है या नहीं।
अब हम ओ (एन) समय में एक के लंबाई की लंबाई को पा सकते हैं, हम बस सबसे बड़ा के खोजने के लिए एक बाइनरी खोज चलाते हैं जिसके लिए हम अपने फ़ंक्शन का उपयोग करके एक गैर-ओवरलैपिंग सबस्ट्रिंग मैच पा सकते हैं। अजगर में
कोड इस प्रकार
A=23
MOD=10007 # use a random value in the real world
def hsh(text):
return sum([ord(c)*A**(len(text)-i-1) for i,c in enumerate(text)])%MOD
def k_substring(text, k):
substrings={}
cur=hsh(text[:k])
pwr=(A**(k-1))%MOD
substrings[cur]=[0]
for i in xrange(k,len(text)):
to_remove=(ord(text[i-k])*pwr)%MOD
to_add=ord(text[i])
cur-=to_remove
if cur<0:
cur+=MOD
cur=(cur*A)%MOD
cur=(cur+to_add)%MOD
if cur in substrings:
lst=substrings[cur]
for index in lst:
if index+k<=i-k+1 and text[index:index+k]==text[i-k+1:i+1]:
return index
lst.append(i-k+1)
else:
substrings[cur]=[i-k+1]
return -1
def longest_substring(text):
hi,lo=len(text),0
while hi>lo:
mid=(hi+lo+1)>>1
if k_substring(text,mid)==-1:
hi=mid-1
else:
lo=mid
index=k_substring(text,lo)
return text[index:index+lo]
(माफ करना अगर यह स्पष्ट नहीं है। यह 6:30 बजे यहाँ है और मैं वास्तव में बिस्तर पर वापस जाने की जरूरत है :))
सिर्फ curious- व्यापार आवेदन क्या इसके लिए? – Beth
यह एक व्यावसायिक अनुप्रयोग नहीं है। यह एक गीत में थीम ढूंढने से संबंधित है और इस समय एक क्यूरियो है जब तक कि मुझे इसमें शामिल एक प्रोजेक्ट नहीं मिलता है। =] –