zoukankan      html  css  js  c++  java
  • 2014年9月28日 18:35:01

    着实是有好几天没有动手写写自己的博客了。这些天感觉自己是被别人的事情搞的一团糟,结果自己反倒是帮不上什么忙的。还是算了吧,先将自己的东西好好的忙好,毕竟还是得自己有能力才能够帮到别人的,没办法,物竞天择适者生存。

    好了,ACM也是告了一个段落,结果等来等去等到了算法课,最终是让自己失望万分,还是赶紧的重操旧业把,好好努力,争取让自己搞出一点成绩来,即使最后是失败了,也是虽败犹荣,亮剑精神嘛。

    今天研究的问题是最长公共子序列,着实由于基础不扎实,网上找了一篇博客,现在将它的解决方案列举出来:

    方法一:枚举法

    主要是将第一个串的所有的子序列全部都列举出来,然后和第二个串进行匹配,这个属于暴力破解法。

    方法二:动态规划

    这里楼主采用的是矩阵的方式来实现的,也就是二维数组。

    先是计算最长公共子序列的长度,然后是根据长度回溯出最长公共子序列。

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

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

    递推方程为:

    不知道大家看懂了没?动态规划的一个重要性质特点就是解决“子问题重叠”的场景,可以有效的避免重复计算,根据上面的

    公式其实可以发现C[i,j]一直保存着当前(Xi,Yi)的最大子序列长度。

     1 #include<stdio.h>
     2 #include<string.h>
     3 char a[30],b[30];
     4 int lena,lenb;
     5 int LCS(int,int);  ///两个参数分别表示数组a的下标和数组b的下标
     6 
     7 int main()
     8 {
     9     strcpy(a,"ABCBDAB");
    10     strcpy(b,"BDCABA");
    11     lena=strlen(a);
    12     lenb=strlen(b);
    13     printf("%d
    ",LCS(0,0));
    14     return 0;
    15 }
    16 
    17 int LCS(int i,int j)
    18 {
    19     if(i>=lena || j>=lenb)
    20         return 0;
    21     if(a[i]==b[j])
    22         return 1+LCS(i+1,j+1);
    23     else
    24         return LCS(i+1,j)>LCS(i,j+1)? LCS(i+1,j):LCS(i,j+1);
    25 }

     下面的这个是根据公式优化出来的代码:

     1 #include <iostream>
     2 #include <string>
     3 #include<stdio.h>
     4 #include<string.h>
     5 
     6 
     7 char a[500],b[500];
     8 char num[501][501]; ///记录中间结果的数组
     9 char flag[501][501];    ///标记数组,用于标识下标的走向,构造出公共子序列
    10 void LCS(); ///动态规划求解
    11 void getLCS();    ///采用倒推方式求最长公共子序列
    12 
    13 using namespace std;
    14 
    15 int main()
    16 {
    17     int i;
    18     strcpy(a,"zhangjie");
    19     strcpy(b,"hetongkang");
    20     memset(num,0,sizeof(num));
    21     memset(flag,0,sizeof(flag));
    22     LCS();
    23     printf("%d
    ",num[strlen(a)][strlen(b)]);
    24     getLCS();
    25     return 0;
    26 }
    27 
    28 void LCS()
    29 {
    30     int i,j;
    31     for(i=1;i<=strlen(a);i++)
    32     {
    33         for(j=1;j<=strlen(b);j++)
    34         {
    35             if(a[i-1]==b[j-1])   ///注意这里的下标是i-1与j-1
    36             {
    37                 num[i][j]=num[i-1][j-1]+1;
    38                 flag[i][j]=1;  ///斜向下标记
    39             }
    40             else if(num[i][j-1]>num[i-1][j])
    41             {
    42                 num[i][j]=num[i][j-1];
    43                 flag[i][j]=2;  ///向右标记
    44             }
    45             else
    46             {
    47                 num[i][j]=num[i-1][j];
    48                 flag[i][j]=3;  ///向下标记
    49             }
    50         }
    51     }
    52 }
    53 
    54 void getLCS()
    55 {
    56 
    57     char res[500];
    58     int i=strlen(a);
    59     int j=strlen(b);
    60     int k=0;    ///用于保存结果的数组标志位
    61     while(i>0 && j>0)
    62     {
    63         if(flag[i][j]==1)   ///如果是斜向下标记
    64         {
    65             res[k]=a[i-1];
    66             k++;
    67             i--;
    68             j--;
    69         }
    70         else if(flag[i][j]==2)  ///如果是斜向右标记
    71             j--;
    72         else if(flag[i][j]==3)  ///如果是斜向下标记
    73             i--;
    74     }
    75 
    76     for(i=k-1;i>=0;i--)
    77         printf("%c",res[i]);
    78 }
    我要坚持一年,一年后的成功才是我想要的。
  • 相关阅读:
    git线上操作
    IDEA快捷方式
    Java 四种线程池
    java 获取当前天之后或之前7天日期
    如何理解AWS 网络,如何创建一个多层安全网络架构
    申请 Let's Encrypt 通配符 HTTPS 证书
    GCE 部署 ELK 7.1可视化分析 nginx
    使用 bash 脚本把 AWS EC2 数据备份到 S3
    使用 bash 脚本把 GCE 的数据备份到 GCS
    nginx 配置 https 并强制跳转(lnmp一键安装包)
  • 原文地址:https://www.cnblogs.com/tianxia2s/p/3998817.html
Copyright © 2011-2022 走看看