需要java函数来查找字符串中最长的重复子字符串

For instance, if the input is"banana",output should be"ana" and we have count the number of times it has appeared in this case it is 2.

解决方法如下

公开课测试{
公共静态void main(String [] args){
System.out.println(findLongestSubstring(" i like ike"));
System.out.println(findLongestSubstring("夫人,我是亚当"));
System.out.println(findLongestSubstring("当生活给您柠檬水时,请做柠檬"));
的System.out.println(findLongestSubstring("香蕉"));
}
public static String findLongestSubstring(String value) {
String[] strings = new String[value.length()];
String longestSub ="";
//strip off a character, add new string to array
for(int i = 0; i < value.length(); i++){
strings[i] = new String(value.substring(i));
}
//debug/visualization
//before sort
for(int i = 0; i < strings.length; i++){
System.out.println(strings[i]);
}
Arrays.sort(strings);
System.out.println();
//debug/visualization
//after sort
for(int i = 0; i < strings.length; i++){
System.out.println(strings[i]);
}
Vector possibles = new Vector();
String temp ="";
int curLength = 0, longestSoFar = 0;
/*
* now that the array is sorted compare the letters
* of the current index to those above, continue until
* you no longer have a match, check length and add
* it to the vector of possibilities
*/
for(int i = 1; i < strings.length; i++){
for(int j = 0; j < strings[i-1].length(); j++){
if (strings[i-1].charAt(j) != strings[i].charAt(j)){
break;
}
else{
temp += strings[i-1].charAt(j);
curLength++;
}
}
//this could alleviate the need for a vector
//since only the first and subsequent longest
//would be added; vector kept for simplicity
if (curLength >= longestSoFar){
longestSoFar = curLength;
possibles.add(temp);
}
temp ="";
curLength = 0;
}
System.out.println("Longest string length from possibles:" + longestSoFar);
//iterate through the vector to find the longest one
int max = 0;
for(int i = 0; i < possibles.size();i++){
//debug/visualization
System.out.println(possibles.elementAt(i));
if (possibles.elementAt(i).length() > max){
max = possibles.elementAt(i).length();
longestSub = possibles.elementAt(i);
}
}
System.out.println();
//concerned with whitespace up until this point
//"lemon" not" lemon" for example
return longestSub.trim();
}
}

有趣的问题,但是您尝试过吗?

stackoverflow.com/questions/2172033/

@khachik,我不知道该如何进行

@Aix,是否具有相同的Java函数,它说使用后缀树

@Deepak如果这是家庭作业,则应将其标记为此类。

是否需要有效?如果没有,那么有一种简单的算法,它只使用一些变量和循环。

@IVIad,您可以为它发布Java函数/算法吗?

@Deepak您可以尝试按照您的想象来实现它,或者有一个关于它的维基百科页面

@deepak:总体结构看起来不错。一些指针:(a)严格不需要curLength(其值始终与j相同)。 (b)不需要温度。您可以只使用strings[i-1].substring(0, j)。 (c)不需要possibles。只需存储到目前为止看到的最长的存储。 (d)如果需要忽略空格,则在比较长度时需要忽略它们。否则,如果答案的长度与答案的长度相同,并且答案的末尾带有空格,那么您会得到错误的答案,然后选择带有空格的答案。

@lijie。请您更改我的代码,让我知道我哪里出错了。

使用后缀数组+ LCP数组,并根据实现以O(n)或O(nlogn)或O(nlog ^ 2n)获得解决方案。它比动态编程方法好得多。另外,由于线性时间方法有很多恒定的开销,因此nlogn实现应该很好地工作。

对于动态编程解决方案,这是一个常见的CS问题。

编辑(对于lijie):

您在技术上是正确的-这不是完全相同的问题。 但是,这并不会使上面的链接变得无关紧要,并且如果提供的两个字符串相同,则可以使用相同的方法(尤其是动态编程)-只需要进行一次修改即可:不要考虑对角线的情况。 或者,正如其他人指出的那样(例如LaGrandMere),请使用后缀树(也在上面的链接中找到)。

编辑(对于Deepak):

可以在此处找到最长公共子字符串的Java实现(使用动态编程)。 请注意,您将需要对其进行修改以忽略"对角线"(请参阅Wikipedia图),否则最长的通用字符串将是它本身!

+1给您提供解决方案的方法,+ 1给您提供aix注释。

问题不是最长的公共子字符串。至少映射不是无关紧要的。请注意,此问题只有1个输入字符串,而LCS问题是获得2个输入字符串之间最长的公用子字符串。

@lijie感谢您让我保持警惕。我已经更新了答案。

@pst,我需要一个字符串中最长的重复子字符串,您的实现将返回" ana"作为答案

@pst:好的,更新很好:)谢谢。

@lijie,答案是否会返回" ana"作为答案

@Deepak:是的。但是,它(DP解决方案)不是最有效的算法(可能是后缀树:O(n))

@lijie,我浏览了一个网站,发现关于相同后缀概念的有用信息非常相似,维护后缀数组,然后对其进行排序,将相邻对之间进行比较,并返回最大的重复子字符串。我应如何实现此算法现在...你能指导我吗?

@Deepak:"这个"算法是什么算法?后缀树,后缀数组还是什么?以及算法的哪一部分?施工?

@lijie:programmingpraxis.com/2010/12/14/longest-duplicated-substring ...他已经解释了这样做的方法。我不知道如何用Java编写相同的代码

@Deepak:主要问题线程中的评论有误。

在Java中:后缀树。

感谢那些找到了解决方法的人,我不知道。