• 算法分析设计实践——最长公共子序列


    算法分析设计实践——最长公共子序列

    1.问题

    对于序列a和序列b,求其最长公共子序列

    2.解析

    通过动态规划的方式

    dp[i][j] 前i个字符的x和前j个字符的y的最长公共子序列

    当a[i] = b[j] 的时候

    dp[i][j] = max(dp[i][j] , dp[i - 1][j - 1] + 1)

    如果第i位和第j位相等的话,那么最长序列长度 + 1

    当 a[i] != b[j] 的时候

    dp[i][j] = max(dp[i][j] , dp[i - 1][j] , dp[i][j - 1])

    如果第i位和第j不相等的话 , 那么最长公共子序列的长度则从 dp[i - 1][j] 和 dp[i][j - 1] 转移过来

    3.设计

     1 void lcs()
     2 {
     3     for (int i = 0; i <= len1; ++i) dp[i][0] = 0;
     4     for (int i = 0; i <= len2; ++i) dp[0][i] = 0;
     5     for (int i = 1; i <= len1; ++i)
     6     {
     7         for (int j = 1; j <= len2; ++j)
     8         {
     9             if (arr[i] == brr[j])
    10                 dp[i][j] = dp[i - 1][j - 1] + 1;
    11             else
    12             {
    13                 if (dp[i - 1][j] > dp[i][j - 1])
    14                 {
    15                     res[i][j] = 1;
    16                     dp[i][j] = dp[i - 1][j];
    17                 }
    18                 else
    19                 {
    20                     res[i][j] = 2;
    21                     dp[i][j] = dp[i][j - 1];
    22                 }
    23             }
    24         }
    25     }
    26 }
    27 string getlcs()
    28 {
    29     int i = len1, j = len2;
    30     string ans = "";
    31     while (i > 0 && j > 0)
    32     {
    33         if (!res[i][j])
    34         {
    35             ans = arr[i] + ans;
    36             i--, j--;
    37         }
    38         else if (res[i][j] == 1)
    39         {
    40             i--; 
    41         }
    42         else
    43         {
    44             j--;
    45         }
    46     }
    47     return ans;
    48 }

    4.分析

    时间复杂度:O(n * m)

    5.源码

     1 #include<cstdio>
     2 #include<string.h>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<vector>
     7 #include<queue>
     8 #include<set>
     9 #include<stack>
    10 #include<map>
    11 #include<cctype>
    12 #define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    13 #define mem(a,x) memset(a,x,sizeof(a))
    14 #define lson rt<<1,l,mid
    15 #define rson rt<<1|1,mid + 1,r
    16 #define P pair<int,int>
    17 #define ull unsigned long long
    18 using namespace std;
    19 typedef long long ll;
    20 const int maxn = 2e5 + 10;
    21 const ll mod = 998244353;
    22 const int inf = 0x3f3f3f3f;
    23 const long long INF = 0x3f3f3f3f3f3f3f3f;
    24 const double eps = 1e-7;
    25 
    26 inline ll read()
    27 {
    28     ll X = 0, w = 0; char ch = 0;
    29     while (!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
    30     while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
    31     return w ? -X : X;
    32 }
    33 
    34 int len1, len2;
    35 int dp[1000][1000];
    36 string arr, brr;
    37 int res[1000][1000];
    38 void lcs()
    39 {
    40     for (int i = 0; i <= len1; ++i) dp[i][0] = 0;
    41     for (int i = 0; i <= len2; ++i) dp[0][i] = 0;
    42     for (int i = 1; i <= len1; ++i)
    43     {
    44         for (int j = 1; j <= len2; ++j)
    45         {
    46             if (arr[i] == brr[j])
    47                 dp[i][j] = dp[i - 1][j - 1] + 1;
    48             else
    49             {
    50                 if (dp[i - 1][j] > dp[i][j - 1])
    51                 {
    52                     res[i][j] = 1;
    53                     dp[i][j] = dp[i - 1][j];
    54                 }
    55                 else
    56                 {
    57                     res[i][j] = 2;
    58                     dp[i][j] = dp[i][j - 1];
    59                 }
    60             }
    61         }
    62     }
    63 }
    64 string getlcs()
    65 {
    66     int i = len1, j = len2;
    67     string ans = "";
    68     while (i > 0 && j > 0)
    69     {
    70         if (!res[i][j])
    71         {
    72             ans = arr[i] + ans;
    73             i--, j--;
    74         }
    75         else if (res[i][j] == 1)
    76         {
    77             i--; 
    78         }
    79         else
    80         {
    81             j--;
    82         }
    83     }
    84     return ans;
    85 }
    86 
    87 int main()
    88 {
    89     cin >> arr >> brr;
    90     len1 = arr.size(), len2 = brr.size();
    91     arr = " " + arr;
    92     brr = " " + brr;
    93     lcs();
    94     cout << "最长公共字串长度: " << dp[len1][len2] << endl;
    95     cout << "最长公共字串: " << getlcs() << endl;
    96     return 0;
    97 }
    完整代码

    https://github.com/BambooCertain/Algorithm.git

  • 相关阅读:
    web.xml+spring mvc基本配置
    REST服务安全-双向认证
    thymeleaf 配置
    jenkins
    linux下ssh/scp无密钥登陆方法
    java编译 Error: Could not find or load main class java执行包main方法
    文本按列导入excel
    linux脚本-判断进程是否存在,从而可以做预警处理..
    Linux中顿号
    >/dev/null 2>&1
  • 原文地址:https://www.cnblogs.com/DreamACMer/p/12799216.html
Copyright © 2020-2023  润新知