查找字符串中重复字符的最长子字符串

时间:2017-07-30 00:40:54

标签: python string algorithm

(这是this codeforces problem

的基础

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

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

我的观察是:

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

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

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

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

    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)
    

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

    感谢阅读!

2 个答案:

答案 0 :(得分:2)

您的计划将失败:

4
0011

它只返回11

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

您可以通过从程序中删除intstr来解决此问题(即将答案保存为字符串而不是整数)。

答案 1 :(得分:1)

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对象中提取的,然后按长度降序排序。代码依赖于输入中的数字不得减少的事实,因此不需要第二种字母类型的候选密码。