-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLongestCommonSubsequence.cpp
134 lines (111 loc) · 2.46 KB
/
LongestCommonSubsequence.cpp
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//最长公共子序列
//是指两个字符串的最长相同的子串,可以相同也可以不同
#include <iostream>
#include <string>
using namespace std;
int diff(int a, int b)
{
if (a > b)
return a;
else
return b;
}
string commonString(int **path,string a,string b)
{
string s = "";
int i = a.size();
int j = b.size();
while (i >=0 && j >=0 && path[i][j] != 0 )
{
if (path[i][j] == 1)//斜上
{
s += a[i - 1];//b[j-1]也行
i--;
j--;
}
else if (path[i][j] == 2)//左边
j--;
else if (path[i][j] == 3)//上边
i--;
}
//将获取的结果反转一下
string reversedS = "";
for (int index = s.size() - 1; index >= 0; index--)
reversedS += s[index];
return reversedS;
}
//使用动态规划来求解,设lcs[i][j]表示a[1...i]与b[1...j]的最长公共子串
void LongestCommonSubsequence(string a, string b)
{
//最优子结构的二维数组
int **lcs = new int*[a.size()+1];
for (int i = 0; i <= a.size(); i++)
lcs[i] = new int[b.size()+1];
for (int i = 0; i <= a.size(); i++)
for (int j = 0; j <= b.size(); j++)
lcs[i][j] = 0;
//记录最长子序列的更新是哪里来的:0表示初始状态,1表示斜上,2表示左边,3表示上边
int **path = new int*[a.size()+1];
for (int i = 0; i <= a.size(); i++)
path[i] = new int[b.size() + 1];
for (int i = 0; i <= a.size(); i++)
for (int j = 0; j <= b.size(); j++)
path[i][j] = 0;
int iIndex = -1;
int jIndex = -1;
int maxLength = 0;
//最优子结构:
//if a[i] != b[i], then lcs[i][j] = max(lcs[i-1][j],lcs[i][j-1]) ;
//if a[i] == b[i], then lcs[i][j] = lcs[i-1][j-1]+1
for (int i = 1; i <= a.size(); i++)
{
for (int j = 1; j <= b.size(); j++)
{
if (a[i - 1] == b[j - 1])
{
lcs[i][j] = lcs[i - 1][j - 1] + 1;
//斜上
path[i][j] = 1;
}
else
{
int left = lcs[i][j-1];
int upper = lcs[i - 1][j];
//lcs[i][j] = diff(lcs[i - 1][j], lcs[i][j - 1]);
if (left > upper)//从左边来
{
lcs[i][j] = left;
path[i][j] = 2;
}
else//从上边来
{
lcs[i][j] = upper;
path[i][j] = 3;
}
}
}
}
//输出这个二维矩阵
for (int i = 0; i <= a.size(); i++)
{
for (int j = 0; j <= b.size(); j++)
cout << lcs[i][j] << " ";
cout << endl;
}
cout << "Path matrix is followed:\n";
//输出路径矩阵
for (int i = 0; i <= a.size(); i++)
{
for (int j = 0; j <= b.size(); j++)
cout << path[i][j] << " ";
cout << endl;
}
cout << "Largest Common String is " << commonString(path,a,b)<<endl;
}
int main()
{
string a = "ABCBDAB";//bab
string b = "BDCABA";//caba
LongestCommonSubsequence(a, b);
return 0;
}