我有一个字符串,如:abcgdfabc
我想做以下事情: input:一个字符串,例如:
abcgdfabc
输出:一个字典(键是“字”,值是它显示的时间),
abc:2
gdf:1
单词是“单词”的最大长度,它应该是贪婪的匹配。
我花了很多时间,并且无法弄明白。 字符串超过5000,它是一个基因组,我们想找出它的关系,我们第一次找到这样的字典以使数据更清晰,有帮助。
答案 0 :(得分:2)
此正则表达式查找字母数字组,可选地跟随任意数量的其他字符,然后再单独查找。然后它重复此列表并删除重复项,并为您提供这些字符组及其出现次数:
import re
s = "eg,abcgdfabc"
for word in set(re.findall(r'(\w+)(\w*?\1)+', s)):
print word, s.count(word)
打印
abc 2
但是,如果我们不确切知道一个单词是什么,那么它会在下面的字符串中找到一个重复单词,尽管还有另一个候选单词:
abcdeabcecd
abc abc <- this will be found
cd cd <- this won't be found
答案 1 :(得分:1)
这是一个丑陋的解决方案:
def parse(s,L=None):
do_return=L is None
if(not s):
return
if(do_return):
L=[]
substr=s[0]
for i in range(1,len(s)-1):
if s[:i] in s[i:]:
substr=s[:i]
else:
L.append(substr)
parse(s.replace(substr,''),L=L)
break
else:
L.append(s)
if(do_return):
LL=[(ss,s.count(ss)) for ss in L] #Count the number of times each substring appears
LLL=[]
#Now some of our (unmatched) substrings will be adjacent to each other.
#We should merge all adjacent unmatched strings together.
while LL:
LLL.append(LL.pop(0))
while LLL[-1][1] == 1 and LL: #check if next is unmatched
if(LL[0][1]==1): #unmatched, merge and remove
LLL[-1]=(LLL[-1][0]+LL[0][0],1)
LL.pop(0)
else: #matched, keep on going.
break
d={}
for k,v in LLL:
d[k]=v
return d
S='eg,abcgdfabc'
print parse(S) #{ 'e':1, 'g':2, ',':1, 'abc': 2, 'df', 1}
当然,这并不像你期望的那样,因为g匹配两次(因为它是贪婪的)......
如果你总是希望以3个为一组进行迭代,那么这将变得更容易(更漂亮):
from collections import defaultdict
def parse(s,stride=3):
d=defaultdict(lambda:0)
while s:
key=s[:stride]
d[key]+=1
s=s[stride:]
#if you need a regular dictionary: dd={}; dd.update(d); return dd
return d
答案 2 :(得分:0)
如果您使用的是Python 2.7 +
>>> from itertools import islice
>>> from collections import Counter
>>> def split_steps(step, sequence):
... it = iter(sequence)
... bits = ''.join(islice(it,step))
... while bits:
... yield bits
... bits = ''.join(islice(it,step))
...
>>> Counter(split_steps(3,'abcdgfabc')).most_common()
[('abc', 2), ('dgf', 1)]