topic: If all characters in a string are in the order in which they appear in the string, then a string called a substring of string two. Note that characters that do not require substring (string one) must appear consecutively in string two. Write a function, enter two strings, ask for their longest common subsequence, and print out the longest common subsequence.
For example: Enter two strings Bdcaba and Abcbdab, string BCBA and Bdab are their longest common subsequence, then output their length 4 and print any one of the subsequence.
Analysis: to find the longest common subsequence (longest Common subsequence, LCS) is a very classic dynamic programming problem, so some of the companies pay attention to the algorithm as microstrategy as a face test.
Full introduction of dynamic planning will take a long time, so I do not intend to discuss the concept of dynamic programming, focusing on the directly related content of LCS. If you are not familiar with dynamic planning, please refer to the relevant algorithm books such as algorithmic discussion.
Consider how the longest common subsequence problem can be decomposed into sub problems, set a= "A0,a1,...,am-1", b= "b0,b1,...,bn-1", and z= "Z0,z1,...,zk-1" as their longest common subsequence. It is not difficult to prove the following nature:
(1) If am-1==bn-1, then zk-1=am-1=bn-1, and "Z0,z1,...,zk-2" is a longest common subsequence of "a0,a1,...,am-2" and "b0,b1,...,bn-2";
(2) If the am-1!=bn-1 is zk-1!=am-1, the implication "Z0,z1,...,zk-1" is a longest common subsequence of "a0,a1,...,am-2" and "b0,b1,...,bn-1";
(3) If the am-1!=bn-1 is zk-1!=bn-1, the implication "z0,z1,...,zk-1" is one of the longest common subsequence of "a0,a1,...,am-1" and "b0,b1,...,bn-2".
In this way, if there is a am-1==bn-1, if there is a common subsequence of a and B, then further solves a child problem, finds the longest common subsequence of "a0,a1,...,am-2" and "b0,b1,...,bm-2", and if am-1!=bn-1, solves two child problems and finds out " One of the longest common subsequence of the A0,a1,...,am-2 "and" b0,b1,...,bn-1 "and" a0,a1,...,am-1 "and" b0,b1,...,bn-2 ", and then the longest common subsequence of the older of both.
Solving:
the introduction of a two-dimensional array c[][], using c[i][j] to record the length of the LCS of X[i] and Y[j, B[i][j] record c[i][j is evaluated by the value of the child question to determine the direction of the search when the longest public string is exported.
We are recursive computations from the bottom up, then the c[i-1][j-1],c[i-1][j] and c[i][j-1] are calculated before the c[i,j is computed. At this time we are based on x[i] = = Y[j] or x[i]!= y[j], you can calculate the c[i][j.
The question is recursively written:
Backtracking outputs the longest common child sequence process:
Algorithm Analysis:
because each call moves at least one step up or to the left (or up and to the left), the maximum number of times (M + N) is encountered when i = 0 or j = 0, and the return begins. The time complexity of the algorithm is θ (m + N) when the return is in the same direction as the recursive call and the number of steps is the same.
The complete implementation code is as follows:
/** find the length of the longest common subsequence of two strings * * Author:liuzhiwei * data:2011-08-15 **/#include "stdio.h" #include "string.h" #inc
Lude "stdlib.h" int lcslength (char* str1, char* str2, int **b) {int i,j,length1,length2,len;
Length1 = strlen (STR1);
Length2 = strlen (STR2); Two-pointer method applies dynamic two-dimensional array int **c = new Int*[length1+1]; A total of length1+1 lines for (i = 0; i < length1+1; i++) c[i] = new int[length2+1]; A total of length2+1 columns for (i = 0; i < length1+1; i++) c[i][0]=0; The No. 0 column is initialized to 0 for (j = 0; J < length2+1; J + +) c[0][j]=0; Line No. 0 is initialized to 0 for (i = 1; i < length1+1; i++) {for (j = 1; j < length2+1; j) {if (str1[i-1]=
=STR2[J-1]//Because c[][] 0 rows 0 columns are not used, c[][] the line I element corresponds to str1 i-1 element {c[i][j]=c[i-1][j-1]+1; b[i][j]=0;
The search direction of the output common substring} else if (C[i-1][j]>c[i][j-1]) {c[i][j]=c[i-1][j];
B[i][j]=1;
} else {c[i][j]=c[i][j-1]; b[i][j]=-1; }}/* for (i= 0 i < length1+1; i++) {for (j = 0; J < length2+1; j) printf ("%d", C[i][j])
;
printf ("\ n");
} */len=c[length1][length2];
for (i = 0; i < length1+1 i++)//release two-dimensional array of dynamically requested delete[] c[i];
Delete[] C;
return Len;
} void Printlcs (int **b, char *str1, int i, int j) {if (i==0 | | j==0) return; if (b[i][j]==0) {Printlcs (b, str1, i-1, j-1); Recursion starts at the back, so it is recursive to the front of the substring, and then the output substring ("%c", Str1[i-1) is started after going to the stream;
C[][] The line I element of the str1 corresponds to the i-1 element} else if (b[i][j]==1) Printlcs (b, str1, I-1, J);
else Printlcs (b, str1, I, j-1);
int main (void) {char str1[100],str2[100];
int I,length1,length2,len;
printf ("Please enter the first string:");
Gets (STR1);
printf ("Please enter a second string:");
Gets (STR2);
Length1 = strlen (STR1);
Length2 = strlen (STR2);
Two-pointer method applies dynamic two-dimensional array int **b = new Int*[length1+1];
for (i= 0; i < length1+1; i++) b[i] = new int[length2+1]; Len=lcslength (str1,stR2,B);
printf ("The length of the longest common subsequence is:%d\n", Len);
printf ("Longest common child sequence is:");
Printlcs (B,STR1,LENGTH1,LENGTH2);
printf ("\ n");
for (i = 0; i < length1+1 i++)//release two-dimensional array of dynamically requested delete[] b[i];
Delete[] B;
System ("pause");
return 0;
}
The effect of the program is shown below:
The second method is:
/** find the length of the longest common subsequence of two strings * * Author:liuzhiwei * data:2011-08-15 **/#include "stdio.h" #include "string.h" #inc
Lude "stdlib.h" int lcslength (char* str1, char* str2)//Get the maximum common substring length of two strings and output the common substring {int i,j,length1,length2;
Length1 = strlen (STR1);
Length2 = strlen (STR2); Two-pointer method applies dynamic two-dimensional array int **c = new Int*[length1+1]; A total of length1+1 lines for (i = 0; i < length1+1; i++) c[i] = new int[length2+1]; A total of length2+1 columns for (i = 0; i < length1+1; i++) c[i][0]=0; The No. 0 column is initialized to 0 for (j = 0; J < length2+1; J + +) c[0][j]=0; Line No. 0 is initialized to 0 for (i = 1; i < length1+1; i++) {for (j = 1; j < length2+1; j) {if (str1[i-1]=
=STR2[J-1]//due to c[][] 0 rows 0 columns are not used, c[][] the line I element corresponds to str1 i-1 element c[i][j]=c[i-1][j-1]+1;
else if (c[i-1][j]>c[i][j-1]) c[i][j]=c[i-1][j];
else c[i][j]=c[i][j-1];
Output common substring char s[100]//;
int len,k;
LEN=K=C[LENGTH1][LENGTH2];
S[k--]= ' "; I=Length1,j=length2;
while (i>0 && j>0) {if (str1[i-1]==str2[j-1]) {s[k--]=str1[i-1];
i--;
j--;
else if (c[i-1][j]<c[i][j-1]) j--;
else i--;
printf ("Longest common substring is:");
Puts (s);
for (i = 0; i < length1+1 i++)//release two-dimensional array of dynamically requested delete[] c[i];
Delete[] C;
return Len;
int main (void) {char str1[100],str2[100];
int Length1,length2,len;
printf ("Please enter the first string:");
Gets (STR1);
printf ("Please enter a second string:");
Gets (STR2);
Length1 = strlen (STR1);
Length2 = strlen (STR2);
Len=lcslength (STR1,STR2);
printf ("The length of the longest common substring is:%d\n", Len);
System ("pause");
return 0;
}
Expansion: Set A, B, and C as three long n strings, which are taken from the alphabet of the same constant size. Design an O (n^3) time algorithm that finds the longest common subsequence of three strings.
idea: With the above 2 strings of the common subsequence is the same idea, but here need to dynamically request a three-dimensional array, three strings of the tail characters are different, consider more of the situation.
/** find the length of the longest common subsequence of three strings * * Author:liuzhiwei * data:2011-08-15 **/#include "stdio.h" #include "string.h" #inc
Lude "stdlib.h" int max1 (int m,int n) {if (m>n) return m;
else return n;
int max2 (int x,int y,int z,int k,int m,int n) {int max=-1;
if (X>max) max=x;
if (Y>max) max=y;
if (Z>max) max=z;
if (K>max) max=k;
if (M>max) max=m;
if (N>max) max=n;
return Max; int Lcslength (char* str1, char* str2, char* str3)//Get the maximum common subsequence length of three strings and output the common subsequence {int i,j,k,length1,length2,length3,
Len
Length1 = strlen (STR1);
Length2 = strlen (STR2);
Length3 = strlen (STR3); Application dynamic three-dimensional array int ***c = new Int**[length1+1]; A total of length1+1 lines for (i = 0; i < length1+1; i++) {C[i] = new int*[length2+1];
A total of length2+1 columns for (j = 0; j<length2+1; j +) C[i][j] = new int[length3+1];
for (i = 0; i < length1+1. i++) {for (j = 0; J < Length2+1; J +) c[i][j][0]=0;
for (i = 0; i < length2+1. i++) {for (j = 0; J < Length3+1; j +) c[0][i][j]=0;
for (i = 0; i < length1+1. i++) {for (j = 0; J < Length3+1; j +) c[i][0][j]=0; for (i = 1; i < length1+1. i++) {for (j = 1; j < Length2+1; J +) {for (k = 1; k < lengt h3+1;
k++) {if (Str1[i-1]==str2[j-1] && str2[j-1]==str3[k-1]) c[i][j][k]=c[i-1][j-1][k-1]+1; else if (Str1[i-1]==str2[j-1] && str1[i-1]!=str3[k-1]) c[i][j][k]=max1 (c[i][j][k-1],c[i-1][j-1)
[K]);
else if (Str1[i-1]==str3[k-1] && str1[i-1]!=str2[j-1]) c[i][j][k]=max1 (c[i][j-1][k],c[i-1][j][k-1)); else if (Str2[j-1]==str3[k-1] && str1[i-1]!=str2[j-1]) c[i][j][k]=max1 (c[i-1][j][k],c[i][j-1][k-1
]); else {c[i][j][k]=max2 (c[i-1][j][k],c[i][j-1][k],c[i][j][k-1],c[i-1][j-1][k],c[i-1][j][k-1],c[i][j-1][k-1]);
}}} Len=c[length1][length2][length3];
for (i = 1; i < length1+1; i++)//Free three-dimensional array of dynamic applications {for (j = 1; j < Length2+1; J +) delete[] c[i][j];
Delete[] c[i];
} delete[] C;
return Len;
int main (void) {char str1[100],str2[100],str3[100];
int Len;
printf ("Please enter the first string:");
Gets (STR1);
printf ("Please enter a second string:");
Gets (STR2);
printf ("Please enter a third string:");
Gets (STR3);
Len=lcslength (STR1,STR2,STR3);
printf ("The length of the longest common subsequence is:%d\n", Len);
System ("pause");
return 0;
}
The effect of the program is shown below: