0

I have made the following Java code for searching for the longest substring that is common between a pair of strings. The code is as follows:

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);
    } 

When I test it with those strings the program returns the string dist that is correct, but when I change the strings to:

String cad1="xyzdistancerttt";
String cad2="abcxtwndistattttt";

I got an index out of bounds exception. Also with the following change:

String cad1="xyzdistancertttttp";
String cad2="abcxtwndistatttttsss";

I have as a result the string cttttt, but it should only print ttttt. Any help?

Thanks

Amit
  • 30,756
  • 6
  • 57
  • 88
Little
  • 3,363
  • 10
  • 45
  • 74
  • 1
    One of your problems is most likely that you increment i inside the j loop which is longer than the i string thereby causing the IOOBE. – ChiefTwoPencils Apr 26 '17 at 04:00

3 Answers3

0

this is a so significant algorithm problem in computer science as Longest common substring problem. you can find several implementation for this algorithm. for example use following codes:

implementation 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;

implementation 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));
}

show wikipedia page for more information : https://en.wikipedia.org/wiki/Longest_common_substring_problem

M2E67
  • 937
  • 7
  • 23
0

I see two things going wrong.

--One of the problems is in

if (cad1.charAt(i)==cad2.charAt(j)){
     seq=seq+cad1.charAt(i);
     i++;
}

As M2E67 showed in his second implementation, you need to check if i is out of the bounds and skip the comparison if it is. Take this example: with your first set of strings, when i = cad1.length-1 and j = cad2.length-2, it will add one to i, make i = cad1.length, and perform cad1.charAt(i) in the next iteration of the for loop--which throws an ArrayIndexOutOfBounds exception.

--The second problem is that you're not checking every possible substring in between the two substrings. In your code, you are skipping a possible starting index every time you do i++. I would pick a starting point in cad1, pick a starting point in cad2, find the number of chars in common proceeding those starting indices, and then pick the next pair of starting indices (it's illustrated in M2E67's code as well).

As for the cttttt output, I'm not sure what's happening.

himty
  • 314
  • 2
  • 13
0

Method longestEqualSubstring takes two strings to find longest equal sustring. It takes 1 character of s1 and compares it to every character of s2. If two characters are equal it goes into while loop to compare next characters of s1 and s2 and stores equal characters in current variable. If current's length is more than previous equal substring, longest becomes 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;
    }

Main method to test:

public static void main(String[] args) {
        String cad1 = "xyzdistancerttttttp";
        String cad2 = "abcxtwndistancetttttttttttttttttttttttss";

        String longestEqualSubstring = longestEqualSubstring(cad1, cad2);
        System.out.println(longestEqualSubstring);
    }

Prints :

distance
Jay Smith
  • 2,331
  • 3
  • 16
  • 27