【问题标题】:How to find a longest consecutive repeated substring in a string?如何在字符串中找到最长的连续重复子字符串?
【发布时间】:2017-05-30 20:57:23
【问题描述】:

为了解密消息,我需要先找到密钥。从给定的信息中,我发现键是字符串的一部分:

str = "251220825122082"

我们可以很容易地得到密钥应该是“2512208”,因为密钥应该被重复用于加密消息。但是,我尝试了很多方法,得到了答案“25122082”,最后又加了一个2,但这只是key的另一个开头。

我试过的方法:

  1. 正则表达式:String repeated = str.replaceAll("(.+?)\\1+", "$1");
  2. LRS Java

这两个提供相同的答案(“25122082”)。

谁能帮我解决这个问题?

谢谢!

【问题讨论】:

  • replaceAll 正在做它应该做的事情:它将 25122082512208 替换为 2512208。字符串末尾仍然有一个“2”,它不会替换它。在这里,由于您试图从字符串中提取信息,replaceAll 是不适合这项工作的工具。使用find 搜索正则表达式,使用group 提取捕获组。 replaceAll 用于将输入字符串的一部分替换为其他字符串,并单独保留输入字符串的其余部分。这不是你在这里想要做的。
  • 你怎么确定 2512208 是关键而不是 25122082?
  • @TimBiegeleisen 不重复,使用该方法我无法得到正确答案。即使使用这个在线演示,我也无法得到正确的答案。 daniel-hug.github.io/longest-repeated-substring
  • @NickZiebert 因为密钥重复。如果 25122082 是关键,那么重复的模式是什么?如果密钥不够长来加密消息,它应该从头开始循环。

标签: java string longest-substring


【解决方案1】:

感谢@ajb,通过使用 find() 和 group() 解决了这个问题。

    String str = "251220825122082";
    Pattern p = Pattern.compile("(.+?)\\1+");
    Matcher m = p.matcher(str);
    while (m.find()) {
        String repeated = m.group(1);
        System.out.println(repeated);
    }

输出:2512208

【讨论】:

  • 我的意思是你可以说m.group(1) 来获取第一组的内容(这与正则表达式中的\\1 或替换字符串中的$1 相同)。 m.group() 为您提供整个匹配的字符串,但 m.group(1) 为您提供所需的密钥。在那之后你不需要另一个replaceAll
  • 谢谢!但是如果key是“5122082”怎么办呢?
  • 如果输入的字符串是上面的str,并且“最长连续重复子串”是key,那么就是模棱两可。 2512208 和 5122082 都符合标准,而且都一样长。如果您有一条规则可以明确 5122082 是键(例如,选择文件中的 last 子字符串以防出现平局),那么可能有一种方法可以调整遵守规则的代码。如果您没有规则,那么就没有解决方案——无法在两者之间做出决定。
  • 这种方法只能得到“第一个重复的字符串”。对于str = "22512208225122082",这种方法得到“2”4 次,而不是正确答案“25122082”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-09
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 2023-03-31
  • 2013-02-21
相关资源
最近更新 更多