如何在大数字串中找到重复的数字子序列?

时间:2016-04-28 04:22:48

标签: java algorithm sequence

有人可以帮我解决问题吗?

问题是:

假设1:我们有未定义的子字符串数(s1,s2,s3,...),每个子字符串是100个数字的序列(整数在20000000和80000000之间),他们是随机选择的。 我们对制作此子字符串的数字和子字符串的数量一无所知。 这里重要的是子字符串中数字的顺序而不是它们之间的关系。

假设2:我们有一个包含数百万个数字的大而长的字符串,这个长字符串是由假设1中提到的子字符串的重复组成的。这个字符串的名称是“S”

我们简化了如下示例: 每个子字符串包含四个数字而不是100个数字,每个数字介于20和80之间,而不是20000000和80000000: 我们有“S”字符串,我们的算法必须从字符串“S”中找到子字符串s1和s2以及s3。

S= 71,59,32,51,45,22,53,25,66,72,71,26,32,28,45,72,59,51,53,66,59,51,53,66,59,51,53,66,22,59,51,25,72,32,26,53,28,66,45,72,71,32,45,72,71,32,45,72, ... .

此算法的输出如下:

S1= 59,51,53,66
S2= 22,25,26,28
S3= 71,32,45,72

注意:如果我们很幸运,子字符串可以在没有组合的情况下以字符串“s”形式出现并且一个接一个地重复。

我想找到子字符串数量的算法(s1,s2,s3s,...) 并且还找到使字符串为“S”的子字符串(s1,s2,s3,...)。

非常感谢。

2 个答案:

答案 0 :(得分:2)

希望这会起作用::

import java.util.*;

public class ComputeSubSequence {

 public static void main(String[] args) {
  String rootString = "59,22,51,25,53,66,26,28,59,51,22,53,25,66,71,26,32,28,45,59,72,51,71,53,66,32,45,72,22,25,26,59,51,28,71,53,32,66,45,72";
  Integer sizeOfSubString = 4;
  List < String > rootList = new ArrayList < String > (Arrays.asList(rootString.split("\\s*,\\s*")));

  Set < String > setValue = new LinkedHashSet < String > ();
  Set < Integer > setValueNew = new LinkedHashSet < Integer > ();
  HashMap < Integer, String > map = new LinkedHashMap < Integer, String > ();

  for (String string: rootList) {
   map.put(Integer.valueOf(string), Integer.valueOf(Collections.frequency(rootList, string)).toString());
   setValue.add(Integer.valueOf(Collections.frequency(rootList, string)).toString());
  }

  for (String string: setValue) {
   for (Map.Entry < Integer, String > entry: map.entrySet()) {
    if (entry.getValue().contains(string)) {
     setValueNew.add(entry.getKey());
    }
   }
  }

  List < Integer > listOfNames = new ArrayList < Integer > (setValueNew);

  Integer j = 0;
  Integer i = 0;
  Integer count = 1;
  for (i = sizeOfSubString; i <= listOfNames.size(); i = i + sizeOfSubString) {
   System.out.println("S" + count + "=" + listOfNames.subList(j, i).toString().replace("]", "").replace("[", ""));
   count++;
   j = j + sizeOfSubString;

  }
 }
}

答案 1 :(得分:0)

查看Knuth Morris Pratt算法或Boyer-Moore算法。没有更多细节,很难说出你究竟要求的是什么,但这些都是非常快速搜索算法。对于Knuth Morris Pratt:

  

通常,当搜索的模式变得更长时,算法会变得更快。

我知道Stack Exchange通常更喜欢具有答案而非链接的答案,但算法非常复杂,以至于链接可以更好地提供服务。他们表现的关键在于他们认识到任何失败的匹配都会提供关于其他必须失败的匹配的大量附加信息。这使得它们可以在超线性时间内运行:它们实际上可以在O(n)时间内进行搜索,而无需实际比较字符串中的每个字符。它是通过认识到,当一场比赛失败时,提供的信息比仅仅一场比赛失败的信息更多。&#34;它还说明了可能会或不会发生的附近比赛。这让他们跳过测试他们可以证明永远不会成为比赛的角色。