实验二 动态规划算法 最长公共子序列问题

简介:

 基本题一:最长公共子序列问题

一、实验目的与要求

1、熟悉最长公共子序列问题的算法;

2、初步掌握动态规划算法;

二、实验题

    若给定序列X={x1,x2,…,xm},则另一序列Z={z1,z2,…,zk},是X的子序列是指存在一个严格递增下标序列{i1,i2,…,ik}使得对于所有j=1,2,…,k有:zj=xij。例如,序列Z={BCDB}是序列X={ABCBDAB}的子序列,相应的递增下标序列为{2357}

给定2个序列XY,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列XY的公共子序列。

给定2个序列X={x1,x2,…,xm}Y={y1,y2,…,yn},找出XY的最长公共子序列。

 

三、实验提示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
include  "stdlib.h"
#include "string.h"
  
void  LCSLength( char  *x , char  *y,intm, int  n,  int  **c,  int  **b)
{
        inti ,j;
        for  (i = 1; i<= m; i++) c[i][0] = 0;
        for  (i = 1; i<= n; i++) c[0][i] = 0;
        for  (i = 1; i<= m; i++)
           for  (j = 1; j <= n; j++)
           {
             if  (x[i]==y[j])
             {
                  c[i][j]=c[i-1][j-1]+1;
                  b[i][j]=1;
             }
             else  if  (c[i-1][j]>=c[i][j-1])
             {
                  c[i][j]=c[i-1][j];
                  b[i][j]=2;
             }
             else
             {    c[i][j]=c[i][j-1];
                  b[i][j]=3;
             }
          }
}
void  LCS(inti , int  j,  char  *x , int  **b)
{
       if  (i ==0 || j==0)  return ;
       if  (b[i][j]== 1)
       {
            LCS(i-1,j-1,x,b);
            printf ( "%c" ,x[i]);
       }
       else  if  (b[i][j]== 2)
            LCS(i-1,j,x,b);
       else  LCS(i,j-1,x,b);
}


四、题目分析

       在求最长公共子序列中,我们可以看出如下规律:

设序列X={x1,x2,&hellip;,xm}Y={y1,y2,&hellip;,yn}的最长公共子序列为Z={z1,z2,&hellip;,zk} ,则

   (1)xm=yn,则zk=xm=yn,且zk-1xm-1yn-1的最长公共子序列。

 

   (2)xm&ne;ynzk&ne;xm,则Zxm-1Y的最长公共子序列。(即:ZX序列中前m个元素所组成的序列与Y序列的最长公共子序列)

 

   (3)xm&ne;ynzk&ne;yn,则ZXyn-1的最长公共子序列。(即:ZY序列中前n个元素所组成的序列与X序列的最长公共子序列)

 

由上面三个条件可得如下公式:

C[][]用来记录最长公共子序列的长度,则:

c[i][j] = <1> 0;                   (ij = 0)

 

<2> c[i-1][j-1] + 1;        (ij > 0  Xi = Yj)(即第iX序列元素与第jY元素相等)

 

<3> max(c[i][j-1] , c[i-1][j])       (ij > 0  Xi != Yj)(当XiYj不等时,取两个式子的最大值,若两者相等则默认取第一个)

 

五,源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
importjava.util.*;
import  java.io.*;
  
public  class  LCS
{
     public  static  void  main(String[] args) {  
         String s1 =  "ABCBDAB" ;  
         String s2 =  "BDCABA" ;  
         LCS cms =  new  LCS();  
         String[] x = cms.init(s1);  
         String[] y = cms.init(s2);  
         int [][] b =  new  int [x.length][y.length];  
  
         System.out.println( "最大子序列的长度为:" +lcsLength(x, y, b));  
         System.out.println( "最大子序列为:" );  
         lcs(x.length- 1 , y.length- 1 , x, b);
    
     public  static  void  lcs(inti,  int  j, String[] x,  int [][] b) {  
         if  (i ==  0  || j ==  0 )  
             return ;  
         if  (b[i][j] ==  1 ) {  
             lcs(i -  1 , j -  1 , x, b);  
             System.out.print(x[i]+ "  " );  
         else  if  (b[i][j] ==  2 )  
             lcs(i -  1 , j, x, b);  
     else
         lcs(i, j -  1 , x, b);  
     }  
  
  
     private  String[] init(String str){  
         String temp = str;  
         String[] s = temp.split( "" );  
         return  s;  
    }
  
    public  static  intlcsLength(String[] x, String[] y,  int [][] b) {  
         int  m = x.length -  1 ;  
         int  n = y.length -  1 ;  
  
         int [][] c =  new  int [m +  1 ][n +  1 ];  
  
         for  (inti =  1 ; i<= m; i++){  
             c[i][ 0 ] =  0 ;  
         }  
         for  (inti =  1 ; i<= n; i++)  
             c[ 0 ][i] =  0 ;  
  
  
         for  (inti =  1 ; i<= m; i++) {  
             for  ( int  j =  1 ; j <= n; j++) {  
                 if  (x[i].equals(y[j])) {  
                     c[i][j] = c[i -  1 ][j -  1 ] +  1 ;  
                     b[i][j] =  1 ;  
                 else  if  (c[i -  1 ][j] >= c[i][j -  1 ]) {  
                     c[i][j] = c[i -  1 ][j];  
                     b[i][j] =  2 ;   
                 else  {  
                     c[i][j] = c[i][j -  1 ];  
                     b[i][j] =  3 ;  
                 }  
             }  
         }  
             return  c[m][n];  
     }  
}


 

结果:

 



本文转自 梦朝思夕 51CTO博客,原文链接:http://blog.51cto.com/qiangmzsx/824842


相关文章
|
19小时前
|
算法 图形学
【计算机图形学】实验一 DDA算法、Bresenham算法
【计算机图形学】实验一 DDA算法、Bresenham算法
9 3
|
19小时前
|
算法 网络协议
【计网·湖科大·思科】实验三 总线型以太网的特性、集线器和交换机的区别、交换机的自学习算法
【计网·湖科大·思科】实验三 总线型以太网的特性、集线器和交换机的区别、交换机的自学习算法
5 1
|
4天前
|
机器学习/深度学习 存储 算法
数据结构与算法 动态规划(启发式搜索、遗传算法、强化学习待完善)
数据结构与算法 动态规划(启发式搜索、遗传算法、强化学习待完善)
11 1
|
25天前
|
算法
代码随想录算法训练营第五十六天 | LeetCode 647. 回文子串、516. 最长回文子序列、动态规划总结
代码随想录算法训练营第五十六天 | LeetCode 647. 回文子串、516. 最长回文子序列、动态规划总结
34 1
|
28天前
|
存储 机器学习/深度学习 算法
上机实验三 图的最小生成树算法设计 西安石油大学数据结构
上机实验三 图的最小生成树算法设计 西安石油大学数据结构
21 1
|
28天前
|
存储 算法 C语言
上机实验四 图的最小生成树算法设计 西安石油大学数据结构
上机实验四 图的最小生成树算法设计 西安石油大学数据结构
23 1
|
29天前
|
搜索推荐
图解基础排序算法(冒泡、插入、选择)(山东大学实验二)
图解基础排序算法(冒泡、插入、选择)(山东大学实验二)
|
1月前
|
算法
算法系列--动态规划--特殊的状态表示--分析重复子问题(下)
算法系列--动态规划--特殊的状态表示--分析重复子问题(下)
15 0
|
1月前
|
算法
算法系列--动态规划--特殊的状态表示--分析重复子问题(上)
算法系列--动态规划--特殊的状态表示--分析重复子问题
18 0
|
1月前
|
算法
算法系列--动态规划--背包问题(5)--二维费用背包问题(下)
算法系列--动态规划--背包问题(5)--二维费用背包问题(下)
14 0