2010-04-18 117 views
9

计算字符串中某个字符的最长连续重复次数的最简单方法是什么?例如,在下面的字符串“B”的最长连续重复:计算Python中重复序列的最长出现次数

my_str = "abcdefgfaabbbffbbbbbbfgbb" 

将是6,因为其他连续重复较短我怎样才能在Python做到这一点(分别为3和2。)?

回答

9

如何正则表达式的例子:

import re 
my_str = "abcdefgfaabbbffbbbbbbfgbb" 
len(max(re.compile("(b+b)*").findall(my_str))) #changed the regex from (b+b) to (b+b)* 
# max([len(i) for i in re.compile("(b+b)").findall(my_str)]) also works 

编辑,矿山与interjays

x=timeit.Timer(stmt='import itertools;my_str = "abcdefgfaabbbffbbbbbbfgbb";max(len(list(y)) for (c,y) in itertools.groupby(my_str) if c=="b")') 
x.timeit() 
22.759046077728271 

x=timeit.Timer(stmt='import re;my_str = "abcdefgfaabbbffbbbbbbfgbb";len(max(re.compile("(b+b)").findall(my_str)))') 
x.timeit() 
8.4770550727844238 
+0

+1帮助恢复部分恢复本网站正则表达式的价值 - 非常勇敢。 – doug 2010-04-19 04:29:35

4

这是我非常无聊,低效,直接的计数方法(interjay的好多了)。请注意,我在这个没有解释器的小文本字段中写了这个,所以我没有对它进行测试,而且我可能犯了一个非常愚蠢的错误,那就是证明没有被捕获。

my_str = "abcdefgfaabbbffbbbbbbfgbb" 
last_char = "" 
current_seq_len = 0 
max_seq_len = 0 

for c in mystr: 
    if c == last_char: 
     current_seq_len += 1 
     if current_seq_len > max_seq_len: 
      max_seq_len = current_seq_len 
    else: 
     current_seq_len = 1 
     last_char = c 

print(max_seq_len) 
+1

您可能需要更新循环中某处的'last_char';除此之外,+1提供真正的*最简单*的方式:这是程序员较少的概念/技能要求的方法。顺便说一句,它不是“无效率”:任何解决方案都需要查看字符串上的所有字符以提供正确的结果,因此它的成本至少为O(n):您的方法的时间成本为O(n),所以它效率很高。稍微提高效率就是更新'else:'块的'max_seq_len',所以每个序列更新一次,而不是每个字符一次。 – 2010-04-18 22:16:21

+0

好吧,忽略我关于更新'last_char'的意见,Ignacio只是修正了它;) – 2010-04-18 22:18:50

+0

Thanks Ignacio;)(我只是意味着你不得不在多少打字方面效率低下) – 2010-04-18 22:35:54

9

这里是一个班轮:

max(len(list(y)) for (c,y) in itertools.groupby(my_str) if c=='b') 

说明:

itertools.groupby将返回的连续的相同字符组,该组中的所有项的迭代器沿。对于每个这样的迭代器,len(list(y))将给出组中的项目数量。取最大值(对于给定的字符)将得到所需的结果。

2

使用运行长度编码:

import numpy as NP 

signal = NP.array([4,5,6,7,3,4,3,5,5,5,5,3,4,2,8,9,0,1,2,8,8,8,0,9,1,3]) 

px, = NP.where(NP.ediff1d(signal) != 0) 
px = NP.r_[(0, px+1, [len(signal)])] 
# collect the run-lengths for each unique item in the signal 
rx = [ (m, n, signal[m]) for (m, n) in zip(px[:-1], px[1:]) if (n - m) > 1 ] 

# get longest: 
rx2 = [ (b-a, c) for (a, b, c) in rx ] 
rx2.sort(reverse=True) 

# returns: [(4, 5), (3, 8)], ie, '5' occurs 4 times consecutively, '8' occurs 3 times consecutively 
+0

如果(n - m)> 1“是”如果(n - m)> = 1“检测到长度为1的运行,不应该” – 2012-08-10 03:43:58

+1

@carlo_hamalainen - no。对检测1的“游程长度”没有真正的兴趣。 – doug 2012-08-10 05:27:42

0

这里是我的代码,效率不高,但似乎工作:

def LongCons(mystring): 
    dictionary = {} 
    CurrentCount = 0 
    latestchar = '' 

    for i in mystring: 
     if i == latestchar: 
      CurrentCount += 1 
      if dictionary.has_key(i): 
       if CurrentCount > dictionary[i]: 
        dictionary[i]=CurrentCount 
     else: 
      CurrentCount = 1 
      dictionary.update({i: CurrentCount}) 
      latestchar = i 
    k = max(dictionary, key=dictionary.get) 
    print(k, dictionary[k]) 
    return