zoukankan      html  css  js  c++  java
  • DP3_最长公共子序列

     1 using System;
     2 namespace ConsoleApplication2
     3 {
     4     public class Program
     5     {
     6         static int[,] martix;
     7 
     8         static string str1 = "cnblogs";
     9         static string str2 = "belong";
    10 
    11         static void Main(string[] args)
    12         {
    13             martix = new int[str1.Length + 1, str2.Length + 1];
    14 
    15             LCS(str1, str2);
    16 
    17             //只要拿出矩阵最后一个位置的数字即可
    18             Console.WriteLine("当前最大公共子序列的长度为:{0}", martix[str1.Length, str2.Length]);
    19 
    20             Console.Read();
    21         }
    22 
    23         static void LCS(string str1, string str2)
    24         {
    25             //初始化边界,过滤掉0的情况
    26             for (int i = 0; i <= str1.Length; i++)
    27                 martix[i, 0] = 0;
    28 
    29             for (int j = 0; j <= str2.Length; j++)
    30                 martix[0, j] = 0;
    31 
    32             //填充矩阵
    33             for (int i = 1; i <= str1.Length; i++)
    34             {
    35                 for (int j = 1; j <= str2.Length; j++)
    36                 {
    37                     //相等的情况
    38                     if (str1[i - 1] == str2[j - 1])
    39                     {
    40                         martix[i, j] = martix[i - 1, j - 1] + 1;
    41                     }
    42                     else
    43                     {
    44                         //比较“左边”和“上边“,根据其max来填充
    45                         if (martix[i - 1, j] >= martix[i, j - 1])
    46                             martix[i, j] = martix[i - 1, j];
    47                         else
    48                             martix[i, j] = martix[i, j - 1];
    49                     }
    50                 }
    51             }
    52         }
    53     }
    54 }
    View Code
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 int MAX(int a, int b)
     6 {
     7     return a>b?a:b;
     8 }
     9 int f(char* x, char* y)
    10 {
    11     if(strlen(x)==0) return 0;
    12     if(strlen(y)==0) return 0;
    13     if(*x == *y) return f(x+1,y+1)+1;
    14     return  MAX(f(x,y+1),f(x+1,y));
    15 }
    16 int main()
    17 {
    18     printf("%d
    ", f("ac","abcd")); //2
    19     printf("%d
    ", f("acebbcde1133","xya33bc11de")); //5
    20     return 0;
    21 }
    View Code
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 int LCSLength(char x[], char y[],int m, int n)
     6 {
     7     /* 计算最长公共子序列的长度 */
     8     int L[m+1][n+1],i, j;
     9     for (i = 0; i <= m; i++) L[i][0] = 0;
    10     for (i = 0; i <= n; i++) L[0][i] = 0;
    11 
    12     for (i = 1; i <= m; i++)
    13     {
    14         for (j = 1; j <= n; j++)
    15         {
    16             if (x[i]==y[j])
    17                 L[i][j]=L[i-1][j-1]+1;
    18             else if (L[i-1][j]>= L[i][j-1])
    19                 L[i][j]= L[i-1][j];
    20             else
    21                 L[i][j]= L[i][j-1];
    22 //            if (x[i]==y[j])
    23 //                L[i][j]=L[i-1][j-1]+1;
    24 //            else
    25 //            {
    26 //                if (L[i-1][j]>= L[i][j-1])
    27 //                    L[i][j]= L[i-1][j];
    28 //                else
    29 //                    L[i][j]= L[i][j-1];
    30 //            }
    31         }
    32     }
    33     return L[m][n];
    34 }
    35 int main()
    36 {
    37     char a[100] = "cnblogs";
    38     char b[100] = "belong";
    39     cout << LCSLength(a, b, strlen(a), strlen(b)) << endl;
    40     return 0;
    41 }
    View Code


    概念:

          举个例子,cnblogs这个字符串中子序列有多少个呢?很显然有27个,比如其中的cb,cgs等等都是其子序列,我们可以看出

    子序列不见得一定是连续的,连续的那是子串。

    分析:

    既然是经典的题目肯定是有优化空间的,并且解题方式是有固定流程的,这里我们采用的是矩阵实现,也就是二维数组。

    第一步:先计算最长公共子序列的长度。

    第二步:根据长度,然后通过回溯求出最长公共子序列。

    现有两个序列X={x1,x2,x3,...xi},Y={y1,y2,y3,....,yi},

    设一个C[i,j]: 保存Xi与Yj的LCS的长度。

    动态规划的一个重要性质特点就是解决“子问题重叠”的场景,可以有效的避免重复计算,根据上面的公式其实可以发现C[i,j]一直保存着当前(Xi,Yi)的最大子序列长度

  • 相关阅读:
    剑指offer---尾到头打印链表
    剑指offer---链表中环的入口结点
    剑指offer---删除链表中重复的结点2
    剑指offer---删除链表中重复的结点
    6.shap以及selector的使用
    7.进度条(ProgressBar)
    5.toogleButton以及Switch
    4.基础控件
    3.触摸事件
    2.点击事件和页面切换
  • 原文地址:https://www.cnblogs.com/ghostTao/p/4409444.html
Copyright © 2011-2022 走看看