2015-09-01 1 views
1

Я ищу способ поиска большой строки для большого количества подстрок одинаковой длины.Поиск сена для нескольких игл равной длины (Python)

Мой текущий метод в основном это:

offset = 0 
found = [] 

while offset < len(haystack): 
    current_chunk = haystack[offset*8:offset*8+8] 
    if current_chunk in needles: 
    found.append(current_chunk) 
    offset += 1 

Это мучительно медленно. Есть ли лучший способ для python?

+0

Насколько велики «сенова» и «иглы» (просьба указать примерный размер, для которого вы хотите, чтобы код работал хорошо)? Кроме того, насколько вероятен каждый кусок/количество кусков в среднем в ваших данных? – liori

ответ

4

Более Pythonic, намного быстрее:

for needle in needles: 
    if needle in haystack: 
     found.append(needle) 

Edit: С некоторыми ограниченного тестирования здесь результаты испытаний

Этот алгоритм: 0,000135183334351

Ваш алгоритм: 0,984048128128

Гораздо быстрее.

+0

Я думаю, что вы хотите «за иглу в иголках», а не за «иглу в стоге сена» (которая будет перебирать символы «сена» и всегда «находят» их позже). Вы также можете использовать 'if needle in haystack' вместо проверки возвращаемого значения' find'. – Blckknght

+0

Да, я быстро набрал его, пропустил, что здесь, неявно использует команду find, например. Использует ли он тот же алгоритм, чтобы найти его? – John

+0

'if needle in haystack' более Pythonic и (обычно) быстрее. – refi64

1

Я думаю, что вы можете разбить его на многоядерном и распараллелить свой поиск. Что-то вроде строк:

from multiprocessing import Pool 

text = "Your very long string" 

""" 
A generator function for chopping up a given list into chunks of 
length n. 
""" 
def chunks(l, n): 
    for i in xrange(0, len(l), n): 
    yield l[i:i+n] 

def searchHaystack(haystack, needles): 
    offset = 0 
    found = [] 

    while offset < len(haystack): 
     current_chunk = haystack[offset*8:offset*8+8] 
     if current_chunk in needles: 
     found.append(current_chunk) 
     offset += 1 
    return(needles) 

# Build a pool of 8 processes 
pool = Pool(processes=8,) 

# Fragment the string data into 8 chunks 
partitioned_text = list(chunks(text, len(text)/8)) 

# Generate all the needles found 
all_the_needles = pool.map(searchHaystack, partitioned_text, needles) 
Смежные вопросы