【问题标题】:Finding the longest substring of repeating characters in a string查找字符串中重复字符的最长子串
【发布时间】:2017-07-30 00:40:54
【问题描述】:

(这是this codeforces problem的基础)

我尽量不寻求有关 codeforces 问题的帮助,除非我真的,真的,卡住了,这恰好是现在。

你的第一个任务是找到火星数据库的密码。为此,您最好的秘密特工已经发现了以下事实: 密码是给定字符串的子字符串,由一系列非递减数字组成 密码尽可能长 密码始终是回文 回文是一个向后读取相同的字符串。赛车、鲍勃和中午是著名的例子。 鉴于这些事实,你能找到数据库所有可能的密码吗? 输入 第一行包含 n,即输入字符串的长度(1 ≤ n ≤ 105)。 下一行包含一个长度为 n 的字符串。该字符串的每个字符都是一个数字。 字符串中的数字按非递减顺序排列。 输出 在第一行,打印可能的密码数量 k。 在接下来的 k 行中,按字母顺序打印可能的密码。

我的观察是:

  1. 非递减字符串中的回文只是一串重复字符(例如“4444”或“11”)

  2. 在字符i上,i的最后一个实例-i的第一个实例+1 =重复字符的长度

  3. 跟踪最大密码长度,然后过滤掉每个小于最大密码长度的项目,保证输出的密码是最大长度

我基于这些观察的解决方案是:

n,s = [input() for i in range(2)]#input

maxlength = 0

results = []


for i in s:
    length = (s.rfind(i)-s.find(i))+1 

    if int(i*(length)) not in results and length>=maxlength:

        results.append(int(i*(length))) 

        maxlength = length 



#filer everything lower than the max password length out
results = [i for i in results if len(str(i))>=maxlength]


#output
print(len(results))

for y in results:
    print(y)

不幸的是,这个解决方案是错误的,实际上并在第 4 次测试用例中失败了。我不明白代码有什么问题,所以我无法修复它。有人可以帮忙吗?

感谢阅读!

【问题讨论】:

  • 是 b/c 失败会生成错误的答案,还是 b/c 需要太长时间?
  • 您的问题基本上归结为查找给定字符串中长度> 1 的回文总数。如果我错了,请纠正我,如果可以的话,请给我一个反例。
  • 它失败了,因为它生成了错误的答案。此外,它不仅意味着给定字符串中长度> 1的回文,还意味着长度> =找到的最长回文。例如,如果我找到一个回文“44”,然后我找到另一个“77777”,我必须丢弃“44”和任何其他较短的回文,因为它不再是最大长度。 幸运的是,Peter de Rivas 好心地指出问题在于将答案存储为整数而不是字符串!

标签: python string algorithm


【解决方案1】:

您的程序将失败:

4
0011

它只会返回11

问题是str(int('00'))的长度等于1。

您可以通过从程序中删除 intstr 调用来修复它(即将答案保存为字符串而不是整数)。

【讨论】:

    【解决方案2】:

    Peter de Rivaz 似乎已发现您的代码存在问题,但是,如果您对解决此问题的其他方法感兴趣,请考虑使用正则表达式。

    import sys
    import re
    
    next(sys.stdin)             # length not needed in Python    
    s = next(sys.stdin)
    
    repeats = r'(.)\1+'
    for match in re.finditer(repeats, s):
        print(match.group())
    

    模式(.)\1+ 将查找所有重复数字的子串。输入输出

    10 3445556788

    应该是:

    44 555 88

    如果re.finditer() 发现没有重复数字,则该字符串要么为空,要么由一系列递增的非重复数字组成。第一种情况被排除,因为 n 必须大于 0。对于第二种情况,输入已经按字母顺序排序,因此只需输出长度和每个数字。

    把它放在一起给出了这个代码:

    import sys
    import re
    
    next(sys.stdin)                 # length not needed in Python
    s = next(sys.stdin).strip()
    
    repeats = r'(.)\1+'
    passwords = sorted((m.group() for m in re.finditer(repeats, s)),
                        key=len, reverse=True)
    
    passwords = [s for s in passwords if len(s) == len(passwords[0])]
    
    if len(passwords) == 0:
        passwords = list(s)
    
    print(len(passwords))
    print(*passwords, sep='\n')
    

    请注意,匹配的子字符串是从match 对象中提取出来的,然后按长度降序排序。该代码依赖于这样一个事实,即输入中的数字不得减少,因此不需要第二个字母排序的候选密码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-31
      • 2011-05-26
      • 2020-12-09
      • 1970-01-01
      • 2016-08-11
      • 1970-01-01
      • 2014-05-09
      • 2013-02-21
      相关资源
      最近更新 更多