1. Solve the longest common subsequence (LongestCommon Susequence)
Problem description: The longest string with the same relative order of characters in the string, such as "adaskas", "qascdccasa"->"adaa"
Basic idea: dynamic programming
If(X[i]=Y[j]) LCS[i,j]=LCS[i-1][j-1];
//If the current characters are the same, then the longest subsequence is moved forward by one position
Else if(X[i]!=y[j]) LCS=max(LCS[i-1][j],LCS[i][j-1]);
//If the current characters are different, then the longest subsequence at this time is the maximum value of each one bit back
Fake code:
The C[] number just records the length of the current longest subsequence, and B[] records the direction of finding the longest subsequence
M=length(X);n=length(Y)
For(i=1:m) B[0][i]=0;
For(i=1:n) B[i][0]=0;//The common subsequence of a string and a string of length 0 must be 0
For(i=1:m)
For(j=1:n)
If(X[i]==Y[j])
B[i][j]=B[i-1][j-1]; C[i][j]=”1”//1 means upper left, 2: left 3: upper
Else if(B[i-1][j]>B[i][j-1]) //B[i][j]=max(B[i-1][j],B[i][j-1];
B[i][j]=B[i-1][j]; C[i][j]=”3”
Else B[i][j]=B[i][j-1]; C[i][j]=”2”
At this time, the number in the bottom right corner of the B matrix is the length of the largest common subsequence
If you want to output the subsequence, you only need to search downward in the C[] matrix according to the direction, and output when B[i][j]='1',
Time complexity: O(mn);
Code:
#include<iostream> #include<string> #include<algorithm> usingnamespace std; int main(){ char str1[] = "abcde"; char str2[] = "abeefcdeghj"; int data[50][50]; int B[50][50]; int len1 =strlen(str1); int len2 =strlen(str2); //cout << len1 << endl; for (int i = 0; i < 50;i++) data[i][0]= data[0][i] = 0; int maxer; for(int i=1;i<=len1;i++) for (int j = 1; j <=len2; j++) { /* maxer =max(data[i][j-1], data[i-1][j]); if(str1[i - 1] == str2[j - 1]) data[i][j]= maxer + 1; else data[i][j]= maxer; */ if (str1[i - 1] !=str2[j - 1]) if (data[i][j - 1]> data[i - 1][j]) { data[i][j]= data[i][j - 1]; B[i][j]= 2;//1 represents the upper left, 2 represents the left, 3 represents the upper, } else { data[i][j]= data[i][j - 1]; B[i][j]= 3;//1 represents the upper left, 2 represents the left, 3 represents the upper, } else { data[i][j]= max(data[i - 1][j], data[i][j - 1]) + 1; B[i][j]= 1; } } for (int i = 0; i <=len1; i++) { for (int j = 0; j <=len2; j++) printf("%d ", data[i][j]); printf("\n"); } int i=len1; int j = len2; string result="",s=""; while (i !=0&&j!=0) { if (B[i][j] == 1) { //printf("%c", str1[i - 1]); result.insert(0,s+str1[i-1]); i--; j--; } elseif (B[i][j] == 2) j--; elseif(B[i][j]==3) i--; else; } cout<< result<<endl; return 0; }
If you want to solve the longest common substring, you only need to find the largest number in B, that is, the length of the longest string. After finding it, output one by one according to the diagonal line until the current value is 0.
Code:
#include<iostream> #include<algorithm> usingnamespace std; /* Find the longest common subsequence: problem description: find the length of the longest common string in two strings, just keep the relative order continuous, no need to be continuous Core code: if (str1[i - 1] == str2[j - 1]) then data[i][j] = data[i - 1][j - 1] +1; Find the longest common substring (algorithm of this program): Problem description: Find the longest common continuous substring of two strings, the substrings must be continuous Core code: if(str1[i-1]==str2[j-1] then data[i][j] = data[i - 1][j - 1] + 1; else data[i][j] = max(data[i - 1][j], data[i][j- 1]); If necessary, you can also record the content of the longest common substring, and add the following content to the code: if(str1[i-1]==str2[j-1] then data[i][j] =data[i - 1][j - 1] + 1; B[i][j]="左上" else if(data[i][j-1]>data[i-1][j]) then data[i][j]=data[i][j-1]; B[i][j]="上" else data[i][j]=data[i-1][j]; B[i][j]="左"; */ int main(){ char str1[] = "abcde"; char str2[] = "abeefcdeghj"; int data[50][50]; int len1 =strlen(str1); int len2 =strlen(str2); //cout << len1 << endl; for (int i = 0; i < 50;i++) data[i][0]= data[0][i] = 0; for(inti=1;i<len1+1;i++) for (int j = 1; j <len2+1; j++) { if (str1[i - 1] ==str2[j - 1]) { data[i][j]= data[i - 1][j - 1] + 1; } else data[i][j]= 0; //data[i][j] = max(data[i - 1][j], data[i][j - 1]); } for (int i = 0; i <len1+1; i++) { for (int j = 0; j<len2+1; j++) cout<< data[i][j] <<" "; cout<< endl; } return 0; }