搜索代码中的索引问题

时间:2017-04-26 03:54:27

标签: java algorithm longest-substring

我已经制作了以下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。 有什么帮助吗?

由于

3 个答案:

答案 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-1j = 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循环以比较s1s2的下一个字符,并在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