Longest Common Subsequence and Longest Common String

Posted by manyamile on Wed, 31 Jul 2019 08:46:44 +0200

Obviously, the longest common subsequence does not necessarily need to be continuous, as long as the sequence of characters is strictly incremental. The longest common string requires character continuity

Subsequence code:

package test;

import java.util.*;
/*
 * This problem is to find the longest common subsequence. The subsequence is not necessarily continuous, it only needs strict increment.
 * For example, the longest common subsequence of abcdeeeee and atttbggcd is abcd length 4
 * 
 * */
public class Main4{
    public static void main(String... args){
        try(Scanner in = new Scanner(System.in)){
            while(in.hasNext()){
            
                String s1 = in.nextLine();
                String s2 = in.nextLine();
                String min1 = s1.length() < s2.length()? s1 : s2;
                String max1 = s1.equals(min1) ? s2 : s1;
                 //dp[i][j]Express i String sum j The longest common string of a string
                char[] min = min1.toCharArray();
                char[] max = max1.toCharArray();
                int[][] dp = new int[max.length+1][max.length+1]; 
                for(int i = 1; i < min.length + 1;i++) {
                    for(int j = 1; j < max.length + 1;j++) {
                        if(min[i-1] == max[j-1]) {
                            dp[i][j] = dp[i-1][j-1] + 1;
                        }else {
                            dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
                        }    
                    }
                }
                
                for(int i = 0; i < min.length + 1; i++) {
                    for(int j = 0; j < max.length + 1;j++) {
                        if(j == max.length)
                            System.out.println(dp[i][j]);
                        else System.out.print(dp[i][j] + "  ");
                    }
                }
                System.out.println("++++++++++++++++++++");
                int flag = 0;
                for(int i = 0; i < min.length + 1;i++) {
                    for(int j = 0; j < max.length + 1; j++) {
                        if(dp[i][j] == flag + 1) {
                            System.out.print(max[j-1]);
                            flag = dp[i][j];
                        }
                    }
                }
            }
        }
    }
}

Longest common string code

package test;

import java.util.*;
public class Main2{
    public static void main(String... args){
        try(Scanner in = new Scanner(System.in)){
            while(in.hasNext()){
            
                String s1 = in.nextLine();
                String s2 = in.nextLine();
                String min1 = s1.length() < s2.length()? s1 : s2;
                String max1 = s1.equals(min1) ? s2 : s1;
                 //dp[i][j]Express i String sum j The longest common string of a string
                char[] min = min1.toCharArray();
                char[] max = max1.toCharArray();
                int[][] dp = new int[max.length+1][max.length+1]; 
                for(int i = 1; i < min.length + 1;i++) {
                    for(int j = 1; j < max.length + 1;j++) {
                        if(min[i-1] == max[j-1]) {
                            dp[i][j] = dp[i-1][j-1] + 1;
                        }
                    }
                }
                
                for(int i = 0; i < min.length + 1; i++) {
                    for(int j = 0; j < max.length + 1;j++) {
                        if(j == max.length)
                            System.out.println(dp[i][j]);
                        else System.out.print(dp[i][j] + "  ");
                    }
                }
                System.out.println("++++++++++++++++++++");
                int flag = 0;
                int MAX = 0;
                int end = 0;
                
                for(int i = 1; i < min.length + 1;i++) {
                    for(int j = 1; j < max.length + 1; j++) {
                        if(dp[i][j] > MAX) {
                            MAX = dp[i][j];
                            end = j;
                        }
                    }
                }
                System.out.println("MAX by:"+ MAX);
                System.out.println("end by:"+ end);
                for(int i = end - MAX ; i < end; i++) {
                    if(i == end - 1) System.out.println(max[i]);
                    else System.out.print(max[i]);
                }
            }
        }
    }
}

Comparing the two codes carefully, we can see that the common subsequence needs to record the results of the subsequence in each loop, and the value of dp is always updated (although the value may not change). The dp value of a common string is updated only when the characters are continuous.

When the common subsequence outputs the result, we can print out the state matrix first. The observation matrix shows that when each group of data changes for the first time, it is the value of the subsequence. such as

Of course, it can also be understood vertically, then print out the value at the first change of min.

Topics: PHP Java