The idea of the largest common subsequence (java code)

First of all, we have to distinguish the difference between a common subsequence and a common substring. The substring must be a continuous-length string in the string, but the subsequence does not have this requirement. As long as the same elements appear in order, they can be counted as the same subsequence.
First of all, given two strings: "ABCBDA B" and "BDCABA", here we first eliminate the violent solution to solve this problem, we can split the large-scale string into smaller parts, we Let str1 and str2 be two strings respectively, str1[i] and str2[j] respectively represent the i-th element and j-th element in the string.

  • We only need to judge several cases when i and j respectively represent the last element at the end of the string. First, if they are equal, it is in str1[0]-str1[i-1] and str2[0]- The maximum common subsequence length in the string of str2[j-1] plus one.
  • If they are not equal, we are in the length of the largest common subsequence in the string of str1[0]-str1[i-1] and str2[0]-str2[j] or str1[0]-str1[i] and str2 [0]-Select the maximum value from the length of the largest common subsequence in the string of str2[j-1] as the final largest common subsequence of the two strings.

After analysis, we do a critical shift, assuming that each element is the last child element in the string, it will only have these three situations, so we use dp[ ][] as a record array to know the final maximum What is the value.

package 经典算法;

import java.util.Scanner;
import java.util.Stack;

public class 最大公共子序列 {
    
    
	public static void main(String[] args) {
    
    
		Scanner in = new Scanner(System.in);
		Stack stack = new Stack();
		String str1 = in.next();
		String str2 = in.next();
		int m = str1.length();
		int n = str2.length();
		int[][] dp = new int[m+1][n+1];
		int[][] bp = new int[m+1][n+1];
		
		for(int i = 1;i <= m;i++) {
    
    
			for(int j = 1;j <= n;j++) {
    
    
				if(str1.charAt(i-1) == str2.charAt(j-1)) {
    
    
					dp[i][j] = dp[i-1][j-1]+1;
					bp[i][j] = 1;
				}
				else if(dp[i-1][j] < dp[i][j-1]) {
    
    
					dp[i][j] = dp[i][j-1];
					bp[i][j] = 2;
				}
				else {
    
    
					dp[i][j] = dp[i-1][j];
					bp[i][j] = 3;
				}
			}
		}
		/*
		//System.out
		for(int i = 0;i <= m;i++) {
			for(int j = 0;j <= n;j++) {
				System.out.print(dp[i][j]+" ");
			}
			System.out.println();
		}
		System.out.println();
		//System.out
		for(int i = 0;i <= m;i++) {
			for(int j = 0;j <= n;j++) {
				System.out.print(bp[i][j]+" ");
			}
			System.out.println();
		}*/
		while(true) {
    
    
			if(m == 0 || n == 0)
				break;
			if(bp[m][n] == 1) {
    
    
				stack.push(str1.charAt(m-1));
				m--;
				n--;
			}
			else if(bp[m][n] == 2)
				n--;
			else
				m--;
		}
		System.out.println("最大公共子序列长度为:"+stack.size());
		int temp = stack.size();
		for(int i = 0;i < temp;i++)
			System.out.print(stack.pop()+" ");
		
	}
}

The bp array is used to record the judgments we make each time, so that we can backtrack later and find the largest common subsequence output. If you don’t need it, you can ignore it yourself. The commented out part of the code is after drawing the two arrays. For debugging purposes, you can also ignore it yourself.

The classic LCS (Longest Common Subsequence) problem can be done in three ways. For example, the most well-known longest common string is based on the problem of LCS, delete the three kinds of judgments, and only judge whether the end elements are equal If it is not equal, the string breaks and returns to 0, and the other strings continue to count, and finally count the longest value of the string in the record array; at most, given an out-of-order string, let you find its longest continuous word What is the string? This can be understood as the LCS solution of the string and the sorted string.

Guess you like

Origin blog.csdn.net/baldicoot_/article/details/107894947