Последним руководством является "идентификатор", для больше на этом и других (например, "Хорошо"), см. мое сообщение на очень последнем Руководстве по проектированию Платформы (2-й выпуск)
Since you're applying this to music, you're probably not looking for 100% matches; there will be expected discrepencies from one instance of the theme to another. You might try looking up gene sequence analysis algorithms - there's lots of this variety of stuff going on there. Try BLAST or other alignment algorithms.
You could also try the WinEPI family of algorithms, as well as various prefix tree implementations of this specific result set (these results allow gaps in the substring; for instance, ABCID and AFBCD both contain ABCD). I actually have a paper on an algorithm that might be worth looking at if you would be interested; I would need to attain distribution authorization, so let me know.
Note that this is actually a VERY complicated subject (to do efficiently) for large datasets.
Source: Research for a year or two on a comparable (theme-detection) topic.
Массив суффиксов - хорошая структура данных для решения этой проблемы.
Решение этой проблемы можно найти в Programming Pearls Джона Бентли.
]Вот простой алгоритм:
(как другой ответ только что опубликованный указывает, что здесь я описываю массив суффиксов.)
Хорошо, вот одна безумная идея .
Создайте функцию, которая определяет, есть ли повторяющаяся подстрока длины k в O (n) (где n - длина текста). Это можно сделать с помощью скользящего хеша (см. Википедию для Алгоритм сопоставления строк Рабина-Карпа ) для генерации всех n хэшей за линейное время и с помощью хеш-таблицы / BST (или карты, или словаря, или любого другого языка вызывает его) для хранения соответствующих позиций подстроки. Перед тем, как вставить текущий хеш в структуру данных, мы проверяем, видели ли мы его раньше. Если это уже было замечено ранее, мы просто ищем индексы, по которым был сгенерирован этот хэш, и проверяем, является ли соответствующая подстрока неперекрывающимся совпадением.
Теперь, когда мы можем найти подстроку длины k за время O (n), мы просто запустите двоичный поиск, чтобы найти наибольшее k, для которого мы можем найти совпадение неперекрывающейся подстроки с помощью нашей функции.
Код в Python следует за
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 утра, и я действительно нужно лечь спать :))
Перед тем, как вставить текущий хеш в структуру данных, мы проверяем, видели ли мы его раньше. Если это уже было замечено ранее, мы просто ищем индексы, по которым был сгенерирован этот хэш, и проверяем, является ли соответствующая подстрока неперекрывающимся совпадением.Теперь, когда мы можем найти подстроку длины k за O (n) время, мы просто запустите двоичный поиск, чтобы найти наибольшее k, для которого мы можем найти совпадение неперекрывающейся подстроки с помощью нашей функции.
Код в Python следует за
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 утра, и я действительно нужно лечь спать :))
Перед тем, как вставить текущий хеш в структуру данных, мы проверяем, видели ли мы его раньше. Если это уже было замечено ранее, мы просто ищем индексы, по которым был сгенерирован этот хэш, и проверяем, является ли соответствующая подстрока неперекрывающимся совпадением.Теперь, когда мы можем найти подстроку длины k за O (n) время, мы просто запустите двоичный поиск, чтобы найти наибольшее k, для которого мы можем найти совпадение неперекрывающейся подстроки с помощью нашей функции.
Код в Python следует за
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 утра, и я действительно нужно лечь спать :))