阿里14年机试-----在text中找出以同样的顺序连续出现在query中的最长连续字母序列的长度

题目:给定一个query和一个text,均由小写字母组成。要求在text中找出以同样的顺序连续出现在query中的最长连续字母序列的长度。例如, query为“acbac”,text为“acaccbabb”,那么text中的“cba”为最长的连续出现在query中的字母序列,因此,返回结果应该为其长度3。请注意程序效率。

解析:本题即求最长公共子字符串,用动态规划算法解决。

动态规划:

1. 令C[i][j]表示Xi 和Yi的最大substring长度,动态转移方程为: 如果Xi==Yi, 则C[i][j]=C[i-1][j-1]+1;

                                                                                                               如果Xi==Yi,则C[i][j]=0;

2.求最长公共子字符串:Longest Common Substring=max{C[i][j], 1<=i<=n, 1<=j<=m}

具体代码:

#include<iostream>
#include<cstring>
using namespace std;


int longest_common_substring(char* s,char* t)
{
    int i,j,len1,len2,m,x,y;
    len1=strlen(s);
    len2=strlen(t);
    int **c;
    c=new int*[len1+1];
    for(i=0;i<len1+1;i++)
        c[i]=new int[len2+1];
    for(i=0;i<len1+1;i++)
        c[i][0]=0;
    for(j=0;j<len2+1;j++)
        c[0][j]=0;
    m=-1;
    for(i=1;i<len1+1;i++)
    {
        for(j=1;j<len2+1;j++)
        {
            if(s[i-1]==t[j-1])
                c[i][j]=c[i-1][j-1]+1;
            else
                c[i][j]=0;
            if(c[i][j]>m)
             { m=c[i][j];
                 x=i;
                 y=j;
             }
        }
    }
    /*
    for(i=0;i<len1+1;i++)
    {
        for(j=0;j<len2+1;j++)
       {
          cout<<c[i][j]<<" ";
       }
       cout<<endl;
    }
*/
    //输出公共子字符串
    char output[100];
    int k=m;
    i=x-1;j=y-1;
    output[k--]='\0';
    while(i>=0&&j>=0)
    {
        if(s[i]==t[j])
        {
            output[k--]=s[i];
            i--;
            j--;
        }
        else
            break;
    }
  //  cout<<output<<endl;  //输出最长字符串成
     int len=strlen(output);
     cout<<len<<endl;

    for(i=0;i<len1+1;i++)
        delete[] c[i];
    delete[] c;
    return m;
}
int main()
{
    char text[100],query[100];
    cin>>text;
    cin>>query;
    longest_common_substring(text,query);
    return 0;
}

点赞