我知道有一种使用自下而上方法的解决方案。但我无法在任何地方使用自上而下的方法找到任何解决方案。这是我用来查找LCS中字符数的代码:
#include <bits/stdc++.h>
using namespace std;
int memo[100][100];
int LCS(string a,string b,int x,int y){
if(x==a.size() || y==b.size())
{ memo[x][y]=0;
return 0;
}
if(a[x]==b[y])
{
if(memo[x][y]==-1){
memo[x][y]=LCS(a,b,x+1,y+1);
}
return 1+ memo[x][y];
}
else
{
if(memo[x][y]==-1)
memo[x][y]=max(LCS(a,b,x+1,y),LCS(a,b,x,y+1));
return memo[x][y];
}
}
int main(int argc, char const *argv[])
{
string a,b;
cin>>a>>b;
memset(memo,-1,sizeof(memo));
cout<<LCS(a,b,0,0)<<endl;
return 0;
}
答案 0 :(得分:2)
在比较两个字符串时,您需要使用memo
来执行此操作。如果它们相等,你会跳到对角线上,如果它们不同,你可以向上看并向左跳跃到主要的那个。
我有一个类似于你的代码。唯一的区别是我从结尾看到字符串的开头:
int lcs(char *x, char *y, int px, int py)
{
int ans;
int m1, m2;
if (memo[px][py] > -1) {
return memo[px][py];
}
if ((px == 0) || (py == 0)) {
ans = 0;
} else if (x[px - 1] == y[py - 1]) {
ans = lcs(x, y, px - 1, py - 1) + 1;
} else {
m1 = lcs(x, y, px , py - 1);
m2 = lcs(x, y, px - 1, py );
//max (m1, m2)
if (m1 > m2) {
ans = m1;
} else {
ans = m2;
}
}
memo[px][py] = ans;
return ans;
}
要致电lcs
,您可以lcs("marvin", "panic", strlen("marvin"), strlen("panic"))
。
因此,我的memo
(考虑到您的解决方案而被倒置)将生成下表:
+-------------------------+
| p a n i c |
+-------------------------+
| | -1 0 0 0 0 0 |
| m | 0 0 0 0 0 0 |
| a | 0 0 1 1 1 1 |
| r | 0 0 1 1 1 1 |
| v | 0 0 1 1 1 1 |
| i | 0 0 1 -1 2 2 |
| n | -1 -1 -1 2 2 2 |
+-------------------------+
要恢复子字符串,我们从两个字符串的末尾开始([6,5])并查找相等的字符。如果它们不相等,我们会在向上的位置查看表格的内容。如果这个位置比左边大,我们就往上走,否则我们走到左边。这表示以下代码:
px = strlen("marvin");
py = strlen("panic");
pos = 0;
while ((px != 0) && (py != 0)) {
if (x[px - 1] == y[py - 1]) {
res[pos++] = x[px - 1];
px--;
py--;
} else if (memo[px - 1][py] > memo[px][py -1]) {
px--;
} else {
py--;
}
}
res[pos] = '\0';
printf("%s\n", strrev(res));
这段代码将从最后开始,然后向左移动,直至找到字符n
(位置F
)。
+-------------------------+
| p a n i c |
+-------------------------+
| | -1 0 0 0 0 0 |
| m | 0 0 0 0 0 0 |
| a | 0 0 1 1 1 1 |
| r | 0 0 1 1 1 1 |
| v | 0 0 1 1 1 1 |
| i | 0 0 P -1 2 2 |
| n | -1 -1 -1 F - - |
+-------------------------+
当找到char n
时,算法位置会跳到左上角(位置P
)。在接下来的步骤中,算法会一直运行,直到与char a
匹配。
+-------------------------+
| p a n i c |
+-------------------------+
| | -1 0 0 0 0 0 |
| m | 0 P 0 0 0 0 |
| a | 0 0 F 1 1 1 |
| r | 0 0 | 1 1 1 |
| v | 0 0 | 1 1 1 |
| i | 0 0 | -1 2 2 |
| n | -1 -1 -1 \ - - |
+-------------------------+
最后一步将继续,直到px
的位置达到零并且算法停止。
+-------------------------+
| p a n i c |
+-------------------------+
| | -1 0 0 0 0 0 |
| m | - - 0 0 0 0 |
| a | 0 0 \ 1 1 1 |
| r | 0 0 | 1 1 1 |
| v | 0 0 | 1 1 1 |
| i | 0 0 | -1 2 2 |
| n | -1 -1 -1 \ - - |
+-------------------------+
Obs:结果为na
,需要还原(an
)。