Deep parsing of the longest common substring _c language

Source: Internet
Author: User
Tags first string strlen
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 that enters two strings, asks for their longest common substring, and prints out the longest common substring.
For example: Enter two strings Bdcaba and Abcbdab, string BCBA and Bdab are their longest common substrings, then output their length 4 and print any substring.
Analysis:To find the longest common substring (longest Common subsequence, LCS) is a very classic dynamic programming problem, so some companies that pay attention to algorithms like MicroStrategy have it 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:
Copy Code code as follows:

/**
Find the length of the longest common substring of two strings
* * Author:liuzhiwei
* * data:2011-08-15
**/
#include "stdio.h"
#include "string.h"
#include "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 to request a dynamic two-dimensional array
int **c = new Int*[length1+1]; Total Length1+1 Line
for (i = 0; i < length1+1; i++)
C[i] = new int[length2+1]; Total 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 first line element of the str1 corresponds to the i-1 element
{
c[i][j]=c[i-1][j-1]+1;
b[i][j]=0; Direction of search when exporting common substrings
}
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 you have to recursively precede the substring and then output the substring from the beginning.
printf ("%c", str1[i-1]); C[][] The first line element of the str1 corresponds to the first I-1 element of the
}
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 to request a 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 substring is:%d\n", Len);
printf ("Longest common substring 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:
Copy Code code as follows:

/**
Find the length of the longest common substring of two strings
* * Author:liuzhiwei
* * data:2011-08-15
**/
#include "stdio.h"
#include "string.h"
#include "Stdlib.h"
int Lcslength (char* str1, char* str2)//Get maximum common substring length of two strings and output common substring
{
int i,j,length1,length2;
Length1 = strlen (STR1);
Length2 = strlen (STR2);
Two-pointer method to request a dynamic two-dimensional array
int **c = new Int*[length1+1]; Total Length1+1 Line
for (i = 0; i < length1+1; i++)
C[i] = new int[length2+1]; Total 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 first line element of the str1 corresponds to the 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;
}

Problem extension: Set A, B, and C to be three long n strings that are taken from the alphabet of the same constant size. Design a time algorithm to find the O (n^3) of the longest common substring of three strings.
Train of thought: with the above 2 strings of the common substring is the same idea, but here need to dynamically apply for a three-dimensional array, three strings of the tail characters are different, consider more of the situation.
Copy Code code as follows:

/**
Find the length of the longest common substring of three strings
* * Author:liuzhiwei
* * data:2011-08-15
**/
#include "stdio.h"
#include "string.h"
#include "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 substring length of three strings and output a common substring
{
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]; Total Length1+1 Line
for (i = 0; i < length1+1; i++)
{
C[i] = new int*[length2+1]; Total 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 < length3+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 substring is:%d\n", Len);
System ("pause");
return 0;
}

The effect of the program is shown below:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.