随笔-28  评论-51  文章-10  trackbacks-0
动态规划的经典应用,其实现在发现,其实质就是利用矩阵或者数组保存历史结果,而不用每次递归求解
关键点:
1.找出问题的递归表达式
2.然后根据表达式,直接转化为矩阵上的数据运算

本问题的递归表达式为:
L[i,j]等于 0      ifi=0 或者 j=0
              等于L[i-1,j-1]+1   ifi>0 ,j>0 ai = bi
              等于 max{L[i,j-1], L[i-1,j]} if i > 0 j>0, ai != bj


纯c实现
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define MAXSIZE 10
 4 static char * LCSarray;
 5 static char *start; //指向LCSarray数组中最长公共字串的开始位置
 6 int findLCS(char*int,  char*int );
 7 
 8 int main()
 9 {
10     char * a = "0xyxxzxyzxy";  //第一位都没有意义
11     char *= "0zxzyyzxxyxxz";
12 
13     LCSarray = (char *)malloc(sizeof(char)*MAXSIZE);//保存最长公共字串的数组容器
14     int LCSNum = findLCS(a,10, b, 12);
15     printf("the result is: %d \n", LCSNum );
16     printf("the result char is: %s \n", start );
17     
18     free(LCSarray);
19      exit(EXIT_SUCCESS);
20 }
21 
22 int findLCS(char * a, int na, char *b, int nb)
23 {
24     int i = 0, j = 0//i代表行下标j代表列下标
25     int t = 0//保存最长公共字串的下标
26     
27     //以下构建矩阵
28     int ** matrix = (int **)malloc(sizeof(int ** (na + 1));
29     for(i =0; i <na+1; i++)
30         matrix[i] = (int *) malloc(sizeof(int* (nb +1));
31     //把第一行第一列都初始化为0
32     for(j = 0; j < nb +1; j++)
33     {
34         matrix[0][j] = 0;
35     }
36     for(i = 0; i < na +1; i++)
37     {
38         matrix[i][0= 0;
39     }
40     //填该矩阵,即求解
41     for(i = 1; i < na + 1; i++)
42     {
43         for(j = 1; j < nb + 1; j++)
44         {
45             if(a[i] == b[j])
46             {
47                 matrix[i][j] = matrix[i-1][j -1+ 1;
48              }
49               else
50                  matrix[i][j] =matrix[i-1][j]>matrix[i][j-1]?matrix[i-1][j]:matrix[i][j-1];            
51         }
52         
53     }
54     //找出一个最大公共字串(一开始还以为是条捷径呢,原来是谬误,
55     //因为只考虑最后一列比较,你不能确定较大值必定包含在全局的最大公共子序列中)
56 //    int max = 0;
57 //    for(i = 1; i < na +1; i++)
58 //    {
59 //        if(matrix[i][nb] > max)
60 //        {
61 //              LCSarray[t++] = a[i];
62 //            max = matrix[i][nb];
63 //         }
64 //    }
65 /*从matrix尾部纵向优先搜索,碰到两个不同值时保存char,一直到第一行(其实最合理的应该最后搜索到matrix[1][1]节点)*/
66     i = na;
67     j = nb;
68     char * p = LCSarray + MAXSIZE-1//指向尾部
69     * p = '\0';
70     while(i>0//纵向搜索
71     {
72         while(matrix[i][j] == matrix[i-1][j])
73         {
74             i--;
75         };
76         *--= a[i];
77         i--;
78         j--;
79     }
80     start = p;
81     //矩阵最后一个元素即是我们所需的最长公共子序列的个数
82     int result = matrix[na][nb];
83     //释放空间
84     for(i =0; i <na+1; i++)
85         free(matrix[i]);
86     free(matrix);
87     return result;
88 }




posted on 2008-04-06 22:51 fullfocus 阅读(2500) 评论(1)  编辑  收藏 所属分类: 算法

评论:
# re: 最长公共子序列问题-c实现 2008-10-01 17:48 | anont
非常感谢  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: