Longest Common Subsequence and Longest Common String

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;

}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324683185&siteId=291194637