zoukankan      html  css  js  c++  java
  • 求最长公共子序列(子序列在原串中可以不连续)

    1.问题描述:

    最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence)。其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。

    2.用途:

    最长公共子序列是一个十分实用的问题,它可以描述两段文字之间的“相似度”,即它们的雷同程度,从而能够用来辨别抄袭。对一段文字进行修改之后,计算改动前后文字的最长公共子序列,将除此子序列外的部分提取出来,这种方法判断修改的部分,往往十分准确。简而言之,百度知道、百度百科都用得上。

    3.动态规划解法:

    动态规划的方法求序列X,Y的最长公共子序列

    以两个序列 X、Y 为例子: 设有二维数组 f[i][j] 表示 X 的 i 位和 Y 的 j 位之前的最长公共子序列的长度,则有:

    f[1][1] = same(1,1);

    f[i][j] = max{f[i-1][j -1] + same(i,j),f[i-1,j],f[i,j-1]}

    其中,same(a,b)当 X 的第 a 位与 Y 的第 b 位完全相同时为“1”,否则为“0”。

    最后f[lenX][lenY]即为最长公共子序列的值。

    该算法的空间、时间复杂度均为O(n^2),经过优化后,空间复杂度可为O(n)。

    4.代码实现:

    #include <cstdlib>   

    #include <iostream>   

    using namespace std;   

    #define N 105   

    int dp[N+1][N+1] ;   

    char str1[N] , str2[N];   

     

    int maxx(int a , int b)   

    {   

      if(a > b)   

        return a ;

      return b ;   

    }   

     

    int LCSL(int len1 , int len2)   

    {   

      int i , j ;   

      int len = maxx(len1 , len2);   

      for( i = 0 ; i <= len; i++ )   

      {   

        dp[i][0] = 0 ;dp[0][i] = 0 ;   

      }   

      for( i = 1 ; i<= len1 ; i++)   

      {

        for( j = 1 ; j <= len2 ; j++)   

        {   

          if(str1[i - 1] == str2[j - 1])   

          {   

            dp[i][j] = dp[i - 1][ j - 1] + 1 ;   

          }   

          else   

          {   

            dp[i][j] = maxx(dp[i - 1][ j ] , dp[i][j - 1]) ;   

          }   

        }

      }  

      return dp[len1][len2];   

    }   

    int main()   

    {   

      while(cin >> str1 >> str2)   

      {   

        int len1 = strlen(str1) ;   

        int len2 = strlen(str2) ;   

        cout<<LCSL(len1 , len2)<<endl;   

      }   

      return 0;   

    }

    内容来自百度百科

  • 相关阅读:
    LeetCode 83. Remove Duplicates from Sorted List (从有序链表中去除重复项)
    LeetCode 21. Merge Two Sorted Lists (合并两个有序链表)
    LeetCode 720. Longest Word in Dictionary (字典里最长的单词)
    LeetCode 690. Employee Importance (职员的重要值)
    LeetCode 645. Set Mismatch (集合不匹配)
    LeetCode 500. Keyboard Row (键盘行)
    LeetCode 463. Island Perimeter (岛的周长)
    115.Distinct Subsequences
    55.Jump Game
    124.Binary Tree Maximum Path Sum
  • 原文地址:https://www.cnblogs.com/BeyondAnyTime/p/2527106.html
Copyright © 2011-2022 走看看