2017-02-06 8 views
2

У меня есть файл, который содержит буквы. Мне нужно найти положение самых длинных повторяющихся букв. Например, если файл содержит aaassdddffccsdddfgssfrsfspppppppppppddsfs, мне нужна программа, которая находит позицию ppppppppppp. Я знаю, что мне нужно использовать функцию .index, чтобы найти место, однако я застрял в цикле.Найти позицию самой длинной повторяющейся буквы

+0

Возможный дубликат [Найти самую длинную последовательность 0 в списке целых чисел] (http://stackoverflow.com/questions/40166522/find-longest-sequence-of-0s-in-the-integer-list) (просто преобразуйте строку в список.) – DyZ

+3

Вы должны опубликуйте [mcve], который показывает нам, что вы пробовали, иначе люди подумают, что вы хотите, чтобы мы сделали домашнее задание для вас. ;) –

+0

Совершенный дубликат этого. Возможно, это домашнее задание. http://stackoverflow.com/questions/2664150/counting-longest-occurence-of-repeated-sequence-in-python –

ответ

1

Вам понадобится цикл всей строки. Следите за каждым новым письмом, с которым вы сталкиваетесь, а также с его индексом и продолжительностью каждой последовательности. Только хранить максимальную последовательность

s = 'aaassdddffccsdddfgssfrsfspppppppppppddsfs' 

max_c = max_i = max_len = None 
cur_c = cur_i = cur_len = None 
for i, c in enumerate(s): 
    if c != cur_c: 
     if max_len is None or cur_len > max_len: 
      max_c, max_i, max_len = cur_c, cur_i, cur_len 
     cur_c = c 
     cur_i = i 
     cur_len = 1 
    else: 
     cur_len += 1 
else: 
    # One last check when the loop completes 
    if max_len is None or cur_len > max_len: 
     max_c, max_i, max_len = cur_c, cur_i, cur_len 

print max_c, max_i, max_len 
3

Использование itertools.groupby:

import itertools 

mystr = 'aaassdddffccsdddfgssfrsfspppppppppppddsfs' 

idx = 0 
maxidx, maxlen = 0, 0 
for _, group in itertools.groupby(mystr): 
    grouplen = sum(1 for _ in group) 
    if grouplen > maxlen: 
     maxidx, maxlen = idx, grouplen 
    idx += grouplen 

Дает IDX и длину самой длинной идентичной подстроки:

>>> print(maxidx, maxlen) 
25, 11 

>>> mystr[25:25+11] 
'ppppppppppp' 
+1

Это определенно намного читаемо, чем 'max (((next (g) [0], sum (1 для _ в g)) для _, g в группе (перечисление (mystr), key = itemgetter (1))) , key = itemgetter (1)) [0] ';) –

0

Вот Oneliner

from itertools import groupby 
from functools import reduce 
[(k, next(g)[0], sum(1 for _ in g)+1) for k, g in groupby(enumerate(
    'aaassdddffccsdddfgssfrsfspppppppppppddsfs'), key=itemgetter(1))] 

Вышеуказанное генерирует (ключ, положение, длина). Вы можете получить максимальную длину на наклеивании уменьшить

from itertools import groupby 
from functools import reduce 
from operator import itemgetter 
reduce(lambda x,y:x if x[2] >= y[2] else y, 
    ((k, next(g)[0], sum(1 for _ in g)+1) for k, g in groupby(enumerate(
    'aaassdddffccsdddfgssfrsfspppppppppppddsfs'), key=itemgetter(1)))) 
+0

вы можете использовать max с ключом = itemgetter (2) вместо сокращения – abcabc

0

Быстрым способом достижения этой цели является использование регулярных выражений, чтобы соответствовать повторяющимся символам с (.)(\1+). Затем мы перебираем все эти результаты с использованием понимания генератора и находим max по длине (key=len). Наконец, найдя самую большую строку, мы называем thestr.index(), чтобы найти, где произошло самое длинным повторено письмо:

import re 
txt = "aaassdddffccsdddfgssfrsfspppppppppppddsfs" 
idx = txt.index(max((''.join(f) for f in re.findall(r"(.)(\1+)", txt)), key=len)) 
print(idx) 

Вот тот же код разбит на этапы:

>>> import re 
>>> txt = "aaassdddffccsdddfgssfrsfspppppppppppddsfs" 
>>> matches = list(''.join(f) for f in re.findall(r"(.)(\1+)", txt)) 
>>> print(matches) 
['aaa', 'ss', 'ddd', 'ff', 'cc', 'ddd', 'ss', 'ppppppppppp', 'dd'] 
>>> longest = max(matches, key=len) 
>>> print(longest) 
ppppppppppp 
>>> print(txt.index(longest)) 
25 
Смежные вопросы