最长公共子序列

最长公共子序列:

求两个序列中最长的公共子序列算法,要区别于最长公共子串(其要求连续)。

如:字符串acdfg与adfc的最长公共子序列为adf。

假设c(i,j)记录序列Xi和Yj的最长公共子序列的长度,满足下列公式:

程序实现:

 1 /***************************************
 2 FileName LongestCommonSubsequence.cpp
 3 Author : godfrey
 4 CreatedTime : 2016/5/1
 5 ****************************************/
 6 #include <iostream>
 7 #include <cstring>
 8 #include <vector>
 9 #include <algorithm>
10 #include <stdio.h>
11 #include <stdlib.h>
12 
13 using namespace std;
14 
15 void LongestCommonSubsequence(const char* str1,const char* str2,string& str){
16     int size1 = (int)strlen(str1);
17     int size2 = (int)strlen(str2);
18     const char* s1 = str1-1;
19     const char* s2 = str2-1;
20     vector<vector<int> >chess(size1+1,vector<int>(size2+1));
21     int i,j;
22     //设置棋局
23     for(i=0;i<=size1;i++)
24         chess[i][0] = 0;
25     for(j=0;j<=size2;j++)
26         chess[0][j] = 0;
27     for(i=1;i<=size1;i++){
28         for(j=1;j<=size2;j++){
29             if(s1[i]==s2[j])
30                 chess[i][j] = chess[i-1][j-1] + 1;
31             else
32                 chess[i][j] = max(chess[i][j-1],chess[i-1][j]);
33         }
34     }
35 
36     i = size1;
37     j = size2;
38     //逆推存储
39     while((i!=0) && (j!=0)){
40         if(s1[i]==s2[j]){
41             str.push_back(s1[i]);
42             i--;
43             j--;
44         }
45         else{
46             if(chess[i][j-1]>chess[i-1][j])
47                 j--;
48             else
49                 i--;
50         }
51     }
52     reverse(str.begin(),str.end());
53 }
54 
55 int main()
56 {
57     const char* str1 = "TCGGATCGACTT";
58     const char* str2 = "AGCCTACGTA";
59     string str;
60     LongestCommonSubsequence(str1,str2,str);
61     cout<<str.c_str()<<endl;
62     return 0;
63 }

运行结果:

说明:事实上,两个字符串可能存在多个子序列长度相同并且最大,因此,最长公共子序列是个序列集合。

转载请注明出处:

C++博客园:godfrey_88

http://www.cnblogs.com/gaobaoru-articles/

 

posted on 2016-05-01 15:24  Brainer-Gao  阅读(253)  评论(0编辑  收藏  举报

导航