zoukankan      html  css  js  c++  java
  • LCS最长公共子串(复习复习)- -

    详细解析LCS:传送通道

    重点:

      

    动态规划算法分以下4个步骤:

    1. 描述最优解的结构
    2. 递归定义最优解的值
    3. 按自底向上的方式计算最优解的值   //此3步构成动态规划解的基础。
    4. 由计算出的结果构造一个最优解。   //此步如果只要求计算最优解的值时,可省略

    解决LCS问题,你要求三个方面的东西:1、LCS(Xm-1,Yn-1)+1;2、LCS(Xm-1,Y),LCS(X,Yn-1);3、max{LCS(Xm-1,Y),LCS(X,Yn-1)}

    show me the code:

     1 Procedure LCS_LENGTH(X,Y);
     2 begin
     3   m:=length[X];
     4   n:=length[Y];
     5   for i:=1 to m do c[i,0]:=0;
     6   for j:=1 to n do c[0,j]:=0;
     7   for i:=1 to m do
     8     for j:=1 to n do
     9       if x[i]=y[j] then
    10         begin
    11           c[i,j]:=c[i-1,j-1]+1;
    12           b[i,j]:="";
    13         end
    14       else if c[i-1,j]≥c[i,j-1] then
    15         begin
    16           c[i,j]:=c[i-1,j];
    17           b[i,j]:="";
    18         end
    19       else
    20         begin
    21           c[i,j]:=c[i,j-1];
    22           b[i,j]:=""
    23         end;
    24   return(c,b);
    25 end;

    uva,10066

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstdio>
     4 
     5 using namespace std;
     6 const int maxn=105;
     7 int lcs[maxn][maxn];
     8 int N1,N2;
     9 int main()
    10 {
    11     int s1[maxn],s2[maxn];
    12     for(int t=1;;t++)
    13     {
    14         scanf("%d %d",&N1, &N2);
    15         if(!N1 && !N2) break;
    16         int i,j;
    17         for(i = 0; i < N1; i++)
    18             scanf("%d",&s1[i]);
    19         for(j = 0; j < N2; j++)
    20             scanf("%d",&s2[j]);
    21         for(i=1;i<=N1;i++)
    22             for(j=1;j<=N2;j++)
    23             {
    24                 if(s1[i-1]==s2[j-1])
    25                     lcs[i][j]=lcs[i-1][j-1]+1;
    26                 else
    27                 {
    28                     lcs[i][j]=max(lcs[i-1][j],lcs[i][j-1]);
    29                 }
    30             }
    31         printf("Twin Towers #%d
    ",t);
    32         printf("Number of Tiles : %d
    
    ",lcs[N1][N2]);
    33     }
    34     return 0;
    35 }

    UVA, 10192

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstdio>
     4 #include <cstdlib>
     5 #include <cstring>
     6 
     7 using namespace std;
     8 const int maxn=105;
     9 int lcs[maxn][maxn];
    10 int m,n;
    11 int main()
    12 {
    13     int t=1;
    14     char s1[maxn],s2[maxn];
    15     while(gets(s1))
    16     {
    17         if(s1[0]=='#') break;
    18         gets(s2);
    19         m=strlen(s1);
    20         n=strlen(s2);
    21         for(int i=1;i<=m;i++)
    22             for(int j=1;j<=n;j++)
    23             {
    24                 if(s1[i-1]==s2[j-1])
    25                     lcs[i][j]=lcs[i-1][j-1]+1;
    26                 else
    27                 {
    28                     lcs[i][j]=max(lcs[i-1][j],lcs[i][j-1]);
    29                 }
    30             }
    31         printf("Case #%d: you can visit at most %d cities.
    ",t++,lcs[m][n]);
    32     }
    33     return 0;
    34 }

    UVA, 531

    两种回溯方式:自顶向下

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <string.h>
     4 #include <string>
     5 #include <cmath>
     6 using namespace std;
     7 
     8 int lcs[101][101];
     9 string s1[101],s2[101],seq[101];
    10 int n1,n2;
    11 int main()
    12 {
    13     int t,i,j;
    14     string s;
    15     while( cin >>s)
    16     {
    17         n1=n2=0;
    18         while( 1)
    19         {
    20             if( s!="#")
    21                 s1[++n1] =s;
    22             else
    23                 break;
    24             cin >>s;
    25         }
    26         while( 1)
    27         {
    28             cin >>s;
    29             if( s!="#")
    30                 s2[++n2] =s;
    31             else
    32                 break;
    33         }
    34         memset( lcs, 0,sizeof( lcs));
    35         for( i=1; i<=n1; i++)
    36             for( j=1; j<=n2; j++)
    37             {
    38                 if( s1[i] ==s2[j] )
    39                     lcs[i][j] = lcs[i-1][j-1] +1;
    40                 else
    41                     lcs[i][j] =max( lcs[i-1][j], lcs[i][j-1]);
    42             }
    43         int ans =lcs[n1][n2];
    44         t= ans;
    45         while( lcs[n1][n2])
    46         {
    47             if( lcs[n1][n2] ==lcs[n1-1][n2]) n1--;
    48             else if( lcs[n1][n2] ==lcs[n1][n2-1]) n2--;
    49             else
    50             {
    51                 seq[--t] =s1[n1];
    52                 n1--; n2--;
    53             }
    54         }
    55         for( i=0; i<ans; i++)
    56             if( !i)
    57                 printf("%s",seq[i].c_str());
    58             else
    59                 printf(" %s",seq[i].c_str());
    60         printf("
    ");
    61     }
    62     return 0;
    63 }

    自底向上:

    引用别人的java代码

     1 import java.util.Random;
     2 
     3 public class LCS{
     4     public static void main(String[] args){
     5 
     6         //设置字符串长度
     7         int substringLength1 = 20;
     8         int substringLength2 = 20;  //具体大小可自行设置
     9 
    10         // 随机生成字符串
    11         String x = GetRandomStrings(substringLength1);
    12         String y = GetRandomStrings(substringLength2);
    13 
    14         Long startTime = System.nanoTime();
    15         // 构造二维数组记录子问题x[i]和y[i]的LCS的长度
    16         int[][] opt = new int[substringLength1 + 1][substringLength2 + 1];
    17 
    18         // 动态规划计算所有子问题
    19         for (int i = substringLength1 - 1; i >= 0; i--){
    20             for (int j = substringLength2 - 1; j >= 0; j--){
    21                 if (x.charAt(i) == y.charAt(j))
    22                     opt[i][j] = opt[i + 1][j + 1] + 1;                                 //参考上文我给的公式。
    23                 else
    24                     opt[i][j] = Math.max(opt[i + 1][j], opt[i][j + 1]);        //参考上文我给的公式。
    25             }
    26         }
    27 
    28         -------------------------------------------------------------------------------------
    29 
    30         理解上段,参考上文我给的公式:
    31 
    32         根据上述结论,可得到以下公式,
    33 
    34         如果我们记字符串Xi和Yj的LCS的长度为c[i,j],我们可以递归地求c[i,j]:
    35 
    36         -------------------------------------------------------------------------------------
    37 
    38         System.out.println("substring1:"+x);
    39         System.out.println("substring2:"+y);
    40         System.out.print("LCS:");
    41 
    42         int i = 0, j = 0;
    43         while (i < substringLength1 && j < substringLength2){
    44             if (x.charAt(i) == y.charAt(j)){
    45                 System.out.print(x.charAt(i));
    46                 i++;
    47                 j++;
    48             } else if (opt[i + 1][j] >= opt[i][j + 1])
    49                 i++;
    50             else
    51                 j++;
    52         }
    53         Long endTime = System.nanoTime();
    54         System.out.println(" Totle time is " + (endTime - startTime) + " ns");
    55     }
    56 
    57     //取得定长随机字符串
    58     public static String GetRandomStrings(int length){
    59         StringBuffer buffer = new StringBuffer("abcdefghijklmnopqrstuvwxyz");
    60         StringBuffer sb = new StringBuffer();
    61         Random r = new Random();
    62         int range = buffer.length();
    63         for (int i = 0; i < length; i++){
    64             sb.append(buffer.charAt(r.nextInt(range)));
    65         }
    66         return sb.toString();
    67     }
    68 }

    UVA, 10100

     1 #include <stdio.h>
     2 #include <iostream>
     3 #include <cctype>
     4 #include <algorithm>
     5 #include <string>
     6 #include <string.h>
     7 #include <vector>
     8 
     9 using namespace std;
    10 int lcs[1010][1010];
    11 int main()
    12 {
    13     char s3[1005],s4[1005];
    14     int k=1;
    15     while(gets(s3))
    16     {
    17         gets(s4);
    18         if(s3[0]=='' || s4[0]=='')
    19         {
    20             printf("%2d. Blank!
    ",k++);
    21             continue;
    22         }
    23         int m=strlen(s3);
    24         int n=strlen(s4);
    25         int i,j;
    26         string s1[1005],s2[1005];  //放全局就wa
    27         int count1=0;
    28         bool flag=false;
    29         for(i=0;i<m;i++)
    30         {
    31             char c=s3[i];
    32             if(isalpha(c) || isdigit(c))
    33             {
    34                 if(!flag)
    35                 {
    36                     count1++;
    37                     s1[count1]+=c;
    38                     flag=true;
    39                 }
    40                 else
    41                     s1[count1]+=c;
    42             }
    43             else
    44                 flag=false;
    45         }
    46         flag=false;
    47         int count2=0;
    48         for(i=0;i<n;i++)
    49         {
    50             char c=s4[i];
    51             if(isalpha(c) || isdigit(c))
    52             {
    53                 if(!flag)
    54                 {
    55                     count2++;
    56                     s2[count2]+=c;
    57                     flag=true;
    58                 }
    59                 else
    60                     s2[count2]+=c;
    61             }
    62             else
    63                 flag=false;
    64         }
    65         for(i=1;i<=count1;i++)
    66             for(j=1;j<=count2;j++)
    67             {
    68                 if(s1[i]==s2[j])
    69                     lcs[i][j]=lcs[i-1][j-1]+1;
    70                 else
    71                     lcs[i][j]=max(lcs[i-1][j],lcs[i][j-1]);
    72             }
    73             printf("%2d. Length of longest match: %d
    ",k++,lcs[count1][count2]);
    74     } 
    75     return 0;
    76 }

     

    活在现实,做在梦里。
  • 相关阅读:
    JavaScript函数调用
    JS数据类型&&typeof&&其他
    JavaScript闭包底层解析
    test
    C# 网页自动填表自动登录 .
    C#中没有id 没有name C#怎么点击按钮
    网页中403错误的含义
    C# 按钮置顶和隐藏
    C# webBrowser 屏蔽网页JS脚本错误弹窗
    HTML5 canvas globalCompositeOperation 设置绘图的顺序
  • 原文地址:https://www.cnblogs.com/do-it-best/p/5351267.html
Copyright © 2011-2022 走看看