如何检查整数中的重复序列

时间:2012-04-23 19:06:57

标签: java regex algorithm

我有一个字母数字字符串,我想检查它中的模式重复只是为了整数。它们应该是连续的。

示例

  1. 12341234qwe 应该告诉我重复 1234
  2. 1234qwe1234 告诉我 1234 重复,因为它不连续。
  3. 12121212 应该被视为 12 被重复,因为这是第一个被发现重复的集合。但是如果有一个算法会在 12 之前找到 1212 作为重复集,那么我猜它必须在 1212 上再次执行这些步骤。
  4. 我的想法是,我可以通过在不同的( <= '0' && >= '9')中迭代并与StringBuilder进行比较来存储整数部分。然后我读到关于对字符串执行FFT并显示重复模式。但是我不知道如何在Java中执行FFT并查找结果,我也希望在不进行信号处理的情况下尝试这样做。我读到了关于KMP模式匹配但只适用于给定输入。还有其他办法吗?

5 个答案:

答案 0 :(得分:55)

我认为你可以借助正则表达式解决这个问题。考虑这样的代码:

String arr[] = {"12341234abc", "1234foo1234", "12121212", "111111111", "1a1212b123123c12341234d1234512345"};
String regex = "(\\d+?)\\1";
Pattern p = Pattern.compile(regex);
for (String elem : arr) {
    boolean noMatchFound = true;
    Matcher matcher = p.matcher(elem);
    while (matcher.find()) {
        noMatchFound = false;
        System.out.println(elem + " got repeated: " + matcher.group(1));
    }
    if (noMatchFound) {
        System.out.println(elem + " has no repeation");
    }
}

<强>输出:

abc12341234abc got repeated: 1234
1234foo1234 has no repeation
12121212 got repeated: 12
12121212 got repeated: 12
111111111 got repeated: 1
111111111 got repeated: 1
111111111 got repeated: 1
111111111 got repeated: 1
1a1212b123123c12341234d1234512345 got repeated: 12
1a1212b123123c12341234d1234512345 got repeated: 123
1a1212b123123c12341234d1234512345 got repeated: 1234
1a1212b123123c12341234d1234512345 got repeated: 12345

说明:

正在使用的正则表达式是(\\d+?)\\1其中

\\d        - means a numerical digit
\\d+       - means 1 or more occurrences of a digit
\\d+?      - means reluctant (non-greedy) match of 1 OR more digits
( and )    - to group the above regex into group # 1
\\1        - means back reference to group # 1
(\\d+?)\\1 - repeat the group # 1 immediately after group # 1

答案 1 :(得分:7)

我不确定您是否熟悉RegularExpressions(RegEx),但此代码有效

String str = "12341234qwe";
String rep = str.replaceAll(".*(.+)\\1.*","$1");
if (rep.equals(str))
    System.out.println(str+" has no repition");
else
    System.out.println(str+" has repition "+rep);
str = "1234qwe1234";
rep = str.replaceAll(".*(.+)\\1.*","$1");
if (rep.equals(str))
    System.out.println(str+" has no repition");
else
    System.out.println(str+" has repition "+rep);

这是教程:http://docs.oracle.com/javase/tutorial/essential/regex/

答案 2 :(得分:6)

我的理论是,您可以使用称为suffix tree的数据结构来实现您想要的目标。

浏览初始字符串,收集每个连续的数字序列并构建其后缀树。对于您的示例,它看起来像(对于前4个后缀):

                  R - root
      |         |          |         |
      |         |          |         |
      |         |          |         | 
  12341234$  2341234$   341234$     41234$

现在,下一个后缀依次为1234 $。但是,在插入时,我们注意到它与第一个后缀的前缀1234匹配。计数器保持并行,并在每次向树添加后缀时递增。

在每一步中,我们将计数器与要插入的当前后缀和与之匹配的子字符串之间的匹配长度进行比较。如果匹配的长度是计数器的倍数,那么我们就重复了。

在上述情况下,当我们插入1234 $时,计数器将为4(从0开始),前缀为12341234 $的匹配长度也为4,因此重复1234。

答案 3 :(得分:3)

首先,您需要为模式定义一些规则。 如果一个模式可以有任意长度,那么你应该开始存储int值(构建模式)并开始检查第一个重复int的重复。

在这种情况下:1234123q 你正在构建1234模式,然后重复1,你应该继续存储它并开始将它与下一个值进行比较。

如何处理模式中的重复?

案件:123124123124

模式123124重复两次。它应该注册为重复,还是在123以来的前4位停止!= 124?

如果您选择将这些案例注册为有效重复,那么您需要开始创建并行模式,以便在您继续构建时检查sime时间。

第一种情况(在第一个NOT重复值处停止)很简单,第二种情况会产生很多parralel模式来构建和同时检查。

到达流的末尾后,您可以使用String提供的现有方法进行搜索。

答案 4 :(得分:-5)

Apache Commons Lang.有一个类org.apache.commons.lang.StringUtils,它有一个计算特定子字符串出现次数的方法。它已经存在,因此您可以直接使用它,而不是创建自己的解决方案。

//First parameter is the string to find and second param is the String to search.
StringUtils.CountMatches("1234","12341234"); 
相关问题