【问题标题】:Trying to find longest Uniform Substring试图找到最长的统一子串
【发布时间】:2020-05-05 18:00:14
【问题描述】:

试图找到最长的统一子串。

假设我有 abbbccda 那么我们必须得到“bbb”的索引位置,即。 [1, 3] 所以它应该返回 [1, 3] 。因为 Uniform Substring 从索引 1 开始,长度为 3 个字符。

其他例子:

"10000111" => [ 1, 4 ]

"aabbbbbCdAA" => [ 2, 5 ]

解决这个问题的python代码是什么

我的代码太长了。忽略打印​​有这么多看输出

x="aaaabbbbCdAA"
LIST1=[]
for char in x:
    if(char not in LIST1 ):
        LIST1.append(char)

print(LIST1)
list1=[]

for i in LIST1:
    list1.append(x.count(i))

print(list1)

Max_length_Charcater= max(list1)
print(Max_length_Charcater)

index_Max_length_Charcater=list1.index(Max_length_Charcater)
print(index_Max_length_Charcater)

y=LIST1[index_Max_length_Charcater]
print(y)

l=index_Max_length_Charcater
start_of_max_length_character=x.find(y)

for i in range(len(x)):
    if(x[i]==y):
        l+=1
print(l)

print("({0},{1})" .format(start_of_max_length_character,l))

【问题讨论】:

  • 你有没有写过代码尝试自己解决这个问题?
  • 有很多不同的方法可以解决这个问题。你的解决方法出现了什么问题?
  • 提示:1) 使用set 来确定每个字符串中的uniq 字符; 2) 使用正则表达式或 Python 字符串方法来查找这些 un​​iq 字符的运行长度; 3) 找到最长运行的索引。
  • 不应该将"aabbbbbCdAA" 的输出改为[2, 6] 吗?
  • 是的,我已经编写了代码,但是代码太长了。

标签: python python-3.x


【解决方案1】:

这是一个正则表达式解决方案:

import re 

strs=("10000111", "aabbbbbCdAA", "abbbccda")

for s in strs:
    uniq=set(s)
    mss=max([max(re.findall(f'{c}+', s), key=len) for c in uniq], key=len)
    print(f'{s}: {s.index(mss)}, {len(mss)}')

打印:

10000111: 1, 4
aabbbbbCdAA: 2, 5
abbbccda: 1, 3

您也可以使用groupby 来执行此操作:

from itertools import groupby 

for s in strs:
    mss=max([''.join(v) for k,v in groupby(s)], key=len)
    print(f'{s}: {s.index(mss)}, {len(mss)}')
# same output

【讨论】:

    【解决方案2】:

    您可以使用带有 zip 的列表推导来匹配字符与其前任字符并识别连续条纹中断的位置。然后,从该位置列表中,您再次使用 zip 获取位置范围(从一个中断到下一个中​​断),您可以将其转换为 (start,length) 元组列表。长度最大的元组就是你想要的那个。

    string = "aabbbbbCdAA"
    
    breaks = [i for i,(a,b) in enumerate(zip(string,string[1:]),1) if a!=b]
    ranges = [ (s,e-s) for s,e in zip([0]+breaks,breaks+[len(string)]) ]
    print(max(ranges,key=lambda r:r[1]))
    

    breaks 列表将包含 [2, 7, 8, 9],它们是字母组的起始位置(隐含位置为零)。

    ranges 列表将通过组合每个组的开头与下一组的开头来形成(再次使用 zip)。这允许计算每个组的重复大小:[(0, 2), (2, 5), (7, 1), (8, 1), (9, 2)]

    如果你胆子大,想深入研究正则表达式,re模块提供了直接获取重复字母子串的方法:

    import re
    
    string     = "aabbbbbCdAA"
    
    streaks,_  = zip(*re.findall(r"((.)\2*)",string))
    longest    = max(streaks,key=len)
    
    print(string.index(longest),len(longest))
    # 2 5
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-12
      • 2023-03-04
      • 2015-06-23
      • 1970-01-01
      • 2019-12-05
      • 1970-01-01
      • 2018-05-13
      相关资源
      最近更新 更多