Longest common sub-sequence
The problem with the longest common subsequence is simply to find the longest subsequence in two strings, where the two meanings are clear:
- SUBSTRING: Represents a contiguous string of characters.
- Subsequence: Represents a discontinuous string of characters.
So what we're looking for here is the discontinuous oldest sequence,
Dynamic planning
Why use dynamic programming here? To put it simply, dynamic programming is an algorithm for reducing the complexity of time, applying an extra space to save the results of each step, and finally finding the optimal solution from these results.
Here's the problem: In general, the current optimal solution is only related to the current moment and the previous moment, and it has nothing to do with the other moments, so that dynamic planning can take effect and reduce complexity.
Analyze LCS
In fact, LCS looks very troublesome, can not find the idea, if the brute force crack may want O (n^4), and this topic use dynamic planning idea is very simple, why compared to the previous problem is not good to find ideas?
Because of the previous dynamic planning problems such as knapsack problem, production line problem, is the result of one-dimensional array space, planning to a linear time, and this topic needs O (m*n) time complexity and space complexity.
So in fact is the m*n
second comparison, each time to save the current optimal solution, you can.
Code Implementation Analysis
Here's the question, is that the result we need is only the length? The output is also included with this sequence string.
Look at the following picture:
As we can see here, we construct a matrix that contains i*j
not only the numerical value (the optimal solution for the current result), but also a direction arrow, which represents the direction we need to walk when we backtrack.
So we save two values here, you can use two two-dimensional matrices, or you can use a struct matrix.
Solution Analysis
In fact, this topic in the dynamic planning to understand, but also very simple. A state transfer function.
This is very well understood, when one of the strings is 0, then it must be 0.
This is a good time to understand when two characters are equal, for example:
abcd
and adcd
, at c
the time of the traversal, we find that there are only a
equal, that is, 1.
So c
equal, that abc
is, and adc
at the time of matching, must ab
be greater than and ad
length 1
, this 1
is c
equal. That is, the same time, is c[i-1][j-1]
bigger than the big one 1
.
The next better understanding, if not equal, must be found in the last time the biggest contrast.
Code
This code only outputs the length of the LCS, and the direction of the resulting array I have stored well, want to traverse, directly from the back and forward the array is good.
////Main.cpp//LCS////Longest common sub-sequence (LCS)////Created by Alps on 15/8/23.//Copyright (c) 2015 Chen. All rights reserved.//#include <iostream>using namespace STD;/** Here you can not define the length, the input string is stored in string, and then use STRING.C_STR () to convert the string into an array. I didn't do it here for convenience. */#ifndef max_length#define MAX_LENGTH //definition string maximum length #endifintMaxnum (intFirstnum,intSecondnum) {returnFirstnum > Secondnum? Firstnum:secondnum;}//define array structure bodystructmatrix{intNumintdirect;};typedefMatrix Matrix;intLCS (Char*stra,Char*STRB,intLengtha,intLENGTHB, Matrix *resultmatrix[]) {if(Lengtha = =0|| LENGTHB = =0) {return 0; } for(inti =0; i < Lengtha; i++) { for(intj =0; J < LENGTHB; J + +) {Resultmatrix[i][j].num =0;//Set all default to a maximum of 0Resultmatrix[i][j].direct =1;//All default directions turn on 0 diagonal, 1 on,-1 left} } for(inti =0; i < Lengtha; i++) { for(intj =0; J < LENGTHB; J + +) {if(Stra[i] = = Strb[j]) {resultmatrix[i+1][j+1].num = Resultmatrix[i][j].num +1; resultmatrix[i+1][j+1].direct =0; }Else{resultmatrix[i+1][j+1].num = Maxnum (resultmatrix[i+1][j].num, resultmatrix[i][j+1].num); resultmatrix[i+1][j+1].direct = resultmatrix[i+1][j].num > resultmatrix[i][j+1].num?1: -1; } } }returnResultmatrix[lengtha][lengthb].num;}intMainintargcConst Char* argv[]) {Char*stra = (Char*)malloc(sizeof(Char) * max_length);Char*STRB = (Char*)malloc(sizeof(Char) * max_length);scanf('%s ', stra);scanf('%s ', StrB);intLengtha = (int)strlen(Stra);intLENGTHB = (int)strlen(StrB); Matrix *resultmatrix[lengtha+1]; for(inti =0; I <= Lengtha; i++) {Resultmatrix[i] = (matrix*)malloc(sizeof(structMatrix) * (lengthb+1)); }intmax = LCS (Stra, StrB, Lengtha, LENGTHB, Resultmatrix);printf("%d\n", Max);STD::cout<<"Hello, world!\n.";return 0;}
Above.? Alps1992
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Algorithm learning-the longest common subsequence (LCS) C + + implementation