最长公共子序列


题目:给定两个字符串,求这两个字符串的最长公共子序列。

例如:cnblog 和 belogn 的最长公共子序列是blog。

0 , i == 0 || j == 0

思路:利用动态规划的思想 C[i][j] = max{C[i-1][j], C[i][j-1]}, x[i] != y[j]

C[i-1][j-1] + 1 , x[i] == y[j]

代码如下:

 1 void LongestCommenSubSequence(char Str1[], int M, char Str2[], int N)
 2 {
 3     assert (Str1 != NULL);
 4 
 5     assert (M > 0);
 6 
 7     assert (Str2 != NULL);
 8 
 9     assert (N > 0);
10 
11     int *C = NULL;
12 
13     if (NULL == (C = (int *)malloc ((M + 1) * (N + 1) * sizeof (int))))
14     {
15         printf ("Fail to malloc space to C.\n");
16         exit (1);
17     }
18 
19     for (int i = 0; i <= M; ++i)
20     {
21         for (int j = 0; j <= N; ++j)
22         {
23             if ((0 == i) || (0 == j))
24             {
25                 // 初始化第0行和第列
26                 C[i * (N + 1) + j] = 0;
27                 continue;
28             }
29 
30             if (Str1[i - 1] == Str2[j - 1])
31             {
32                 // C[i][j] = C[i - 1][j-1] + 1
33                 C[i * (N + 1) + j] = C[(i - 1) * (N + 1) + (j - 1)] + 1;
34             }
35             else
36             {
37                 // C[i][j] = max{C[i-1][j], C[i][j-1]}
38                 C[i * (N + 1) + j] = C[(i - 1) * (N + 1) + j] > C[i * (N + 1) + (j - 1)] ? C[(i - 1) * (N + 1) + j] : C[i * (N + 1) + (j - 1)];
39             }
40         }
41     }
42 
43     // 定义一个栈用来保存最长序列,因为是回溯法找,最先找到的字符要最后输出
44     char Stack[MAX];
45     int nTop = -1;
46     int i = M;
47     int j = N;
48 
49     bool bFlag = true;
50 
51     while (bFlag)
52     {
53         if ((C[i * (N + 1) + j] > C[(i - 1) * (N + 1) + (j - 1)]) && (C[i * (N + 1) + j] > C[(i - 1) * (N + 1) + j]))
54         {
55             // 说明Str1[i] == Str2[j],入栈
56             Stack[++nTop] = Str1[i - 1];
57         }
58 
59         if ((0 == C[(i - 1) * (N + 1) + (j - 1)]) && (0 == C[(i - 1) * (N + 1) + j]))
60         {
61             // 上面和左上角元素都为0,说明没有必要再回溯
62             bFlag = false;
63             continue;
64         }
65 
66         // 寻找回溯的方向
67         if (C[(i - 1) * (N + 1) + j] > C[(i - 1) * (N + 1) + (j - 1)])
68         {
69             // 上面大,就往上面走
70             --i;
71         }
72         else
73         {
74             // 否则都往左上角方向走
75             --i;
76             --j;
77         }
78     }
79 
80     if (-1 == nTop)
81     {
82         printf ("这两个字符串没有公共子序列.\n");
83         return;
84     }
85 
86     printf ("这两个字符串的最长公共子序列为:\n");
87 
88     while (nTop >= 0)
89     {
90         printf ("%c", Stack[nTop--]);
91     }
92 
93     printf ("\n");
94 }

测试结果:

优质内容筛选与推荐>>
1、清理IOS项目未使用图片脚本
2、Javascript 蛤蟆可以吃队友,也可以吃对手 比较字符串
3、回归测试测试用例选择方法
4、pymysql连接数据库报错:'NoneType' object has no attribute 'encoding'
5、实验十三:面向对象基础 8、继承实训


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号