我已经制作了以下Java代码,用于搜索一对字符串之间常见的最长子字符串。代码如下:
public static void main(String[] args) {
// TODO code application logic here
String cad1="xyzdistancerttp";
String cad2="abcxtwndistattttt";
String seq, lcs;
seq="";
lcs="";
System.out.println(cad1.length());
for (int i=0;i<cad1.length();i++){
for (int j=0;j<cad2.length();j++){
if (cad1.charAt(i)==cad2.charAt(j)){
seq=seq+cad1.charAt(i);
i++;
}
else{
if (seq.length()>lcs.length()){
lcs=seq;
seq="";
}
}
}
}
System.out.println(lcs);
}
当我用这些字符串测试时,程序返回正确的字符串dist,但是当我将字符串更改为:
String cad1="xyzdistancerttt";
String cad2="abcxtwndistattttt";
我有一个超出范围的索引异常。还有以下变化:
String cad1="xyzdistancertttttp";
String cad2="abcxtwndistatttttsss";
我的结果是字符串cttttt,但它应该只打印ttttt。 有什么帮助吗?
由于
答案 0 :(得分:0)
这是计算机科学中一个如此重要的算法问题,也就是最常见的子串问题。你可以找到这个算法的几个实现。例如,使用以下代码:
实施1:
public static int longestSubstr(String first, String second) {
int maxLen = 0;
int s1= first.length();
int s2 = second.length();
int[][] table = new int[s1+1][s2+1];
for (int i = 1; i <= s1; i++) {
for (int j = 1; j <= s2; j++) {
if (first.charAt(i-1) == second.charAt(j-1)) {
table[i][j] = table[i - 1][j - 1] + 1;
if (table[i][j] > maxLen)
maxLen = table[i][j];
}
}
}
return maxLen;
实施2:
private static String longestCommonSubstring(String S1, String S2)
{
int Start = 0;
int Max = 0;
for (int i = 0; i < S1.length(); i++)
{
for (int j = 0; j < S2.length(); j++)
{
int x = 0;
while (S1.charAt(i + x) == S2.charAt(j + x))
{
x++;
if (((i + x) >= S1.length()) || ((j + x) >= S2.length())) break;
}
if (x > Max)
{
Max = x;
Start = i;
}
}
}
return S1.substring(Start, (Start + Max));
}
显示维基百科页面以获取更多信息:https://en.wikipedia.org/wiki/Longest_common_substring_problem
答案 1 :(得分:0)
我发现有两件事情出错了。
- 其中一个问题是
if (cad1.charAt(i)==cad2.charAt(j)){
seq=seq+cad1.charAt(i);
i++;
}
正如M2E67在他的第二个实现中所示,您需要检查i
是否超出范围并跳过比较(如果是)。举个例子:使用第一组字符串,在i = cad1.length-1
和j = cad2.length-2
时,它会在i
中添加一个,生成i = cad1.length
,然后执行cad1.charAt(i)
for循环的下一次迭代 - 抛出一个ArrayIndexOutOfBounds异常。
- 第二个问题是你没有检查两个子串之间的每个可能的子串。在您的代码中,每次执行i++
时都会跳过可能的起始索引。我会在cad1中选择一个起点,在cad2中选择一个起点,找到共同进行那些起始指数的字符数,然后选择下一对起始指数(它在M2E67&#39;中说明了它)代码也是如此。
关于cttttt输出,我不确定发生了什么。
答案 2 :(得分:0)
方法longestEqualSubstring
需要两个字符串才能找到最长的相等的sustring。
它需要s1
的1个字符,并将其与s2
的每个字符进行比较。如果两个字符相等,则进入while
循环以比较s1
和s2
的下一个字符,并在current
变量中存储相等的字符。如果current
的长度超过之前的相等子字符串,则longest
变为current
。
private static String longestEqualSubstring(String s1, String s2) {
String longest = "", current = "";
for (int i = 0; i < s1.length(); i++)
for (int j = 0; j < s2.length(); j++) {
if (s1.charAt(i) == s2.charAt(j)) {
int ii = i, jj = j;
while (ii < s1.length() && jj < s2.length() && s1.charAt(ii) == s2.charAt(jj)) {
current += s1.charAt(ii);
ii++;
jj++;
}
if (current.length() > longest.length())
longest = current;
current = "";
}
}
return longest;
}
测试的主要方法:
public static void main(String[] args) {
String cad1 = "xyzdistancerttttttp";
String cad2 = "abcxtwndistancetttttttttttttttttttttttss";
String longestEqualSubstring = longestEqualSubstring(cad1, cad2);
System.out.println(longestEqualSubstring);
}
打印:
distance