zoukankan      html  css  js  c++  java
  • 求最大公共字符串

    LCS(Longest Common Subsequence) 就是求两个字符串最长公共子串的问题。

    比如:

      String str1 = new String("adbccadebbca");
      String str2 = new String("edabccadece");
    str1与str2的公共子串就是bccade.

        解法就是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0。然后求出对角线最长的1序列,其对应的位置就是最长匹配子串的位置.

        下面是字符串21232523311324和字符串312123223445的匹配矩阵,前者为X方向的,后者为Y方向的。不难找到,红色部分是最长的匹配子串。通过查找位置我们得到最长的匹配子串为:21232


      0 0 0 1 0 0 0 1 1 0 0 1 0 0 0
      0 1 0 0 0 0 0 0 0 1 1 0 0 0 0
      1 0 1 0 1 0 1 0 0 0 0 0 1 0 0
      0 0 0 0 0 0 0 0 1 1 0 0 0 0
      1 0 0 1 0 1 0 0 0 0 0 1 0 0
      0 0 0 1 0 0 0 1 1 0 0 1 0 0 0
      1 0 1 0 1 0 1 0 0 0 0 0 1 0 0
      1 0 1 0 1 0 1 0 0 0 0 0 1 0 0
      0 0 0 1 0 0 0 1 1 0 0 1 0 0 0
      0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
      0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
      0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    但是在0和1的矩阵中找最长的1对角线序列又要花去一定的时间。通过改进矩阵的生成方式和设置标记变量,可以省去这部分时间。下面是新的矩阵生成方式: 
      0 0 0 1 0 0 0 1 1 0 0 1 0 0 0
      0 1 0 0 0 0 0 0 0 2 1 0 0 0 0
      1 0 2 0 1 0 1 0 0 0 0 0 1 0 0
      0 2 0 0 0 0 0 0 0 1 1 0 0 0 0
      1 0 3 0 1 0 1 0 0 0 0 0 1 0 0
      0 0 0 0 0 0 2 1 0 0 1 0 0 0
      1 0 1 0 5 0 1 0 0 0 0 0 2 0 0
      1 0 1 0 1 0 1 0 0 0 0 0 1 0 0
      0 0 0 2 0 0 0 2 1 0 0 1 0 0 0
      0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
      0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
      0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    当字符匹配的时候,我们并不是简单的给相应元素赋上1,而是赋上其左上角元素的值加一。我们用两个标记变量来标记矩阵中值最大的元素的位置,在矩阵生成的过程中来判断当前生成的元素的值是不是最大的,据此来改变标记变量的值,那么到矩阵完成的时候,最长匹配子串的位置和长度就已经出来了。

      这样做速度比较快,但是花的空间太多。我们注意到在改进的矩阵生成方式当中,每生成一行,前面的那一行就已经没有用了。因此我们只需使用一维数组即可。最终的代码如下:

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


    int main()
    {
    string s1,s2;
    char ch;
    ch=getchar();
    while(ch!=' ')
    {
    s1+=ch;
    ch=getchar();
    }
    while(cin>>ch)
    {
    s2+=ch;
    }
    int len1,len2;
    len1=s1.size();
    len2=s2.size();
    int *a=new int[len1];
    int max=0;
    int i=0,j=0;
    for(i=0;i<len1;i++)
    s1[i]=tolower(s1[i]);
    for(i=0;i<len2;i++)
    s2[i]=tolower(s2[i]);
    for(i=0;i<len2;i++)
    {
    for(j=len1-1;j>=0;j--)
    {
    if(s2[i]==s1[j])
    {
    if(i==0||j==0)
    a[j]=1;
    else
    a[j]=a[j-1]+1;
    if(a[j]>max)
    max=a[j];
    }
    else 
    a[j]=0;
    }
    }
    cout<<max<<endl;
    return 0;
    }

  • 相关阅读:
    让HTML5来为你定位(转)
    Web开发者应知的URL编码知识(转)
    Web开发:URL编码与解码(转)
    用virtualenv建立多个Python独立开发环境(转)
    使用Ajax方式POST JSON数据包(转)
    俞敏洪:我和马云就差了8个字...(转)
    HTTP返回码中301与302的区别(转)
    Postgresql 正则表达式(转)
    【双十一狂欢,一触即发!】安全圈的学习节|绝对省钱攻略
    安全运维中基线检查的自动化之ansible工具巧用
  • 原文地址:https://www.cnblogs.com/fangyan5218/p/10618269.html
Copyright © 2011-2022 走看看