您的位置:首页 > 产品设计 > UI/UE

Longest Common Subsequence

2017-04-07 15:35 232 查看

Longest Common Subsequence

最長共通部分列

最長共通部分列問題 (Longest Common Subsequence problem: LCS)は、2つの与えられた列 X={x1,x2,...,xm} と Y={y1,y2,...,yn} の最長共通部分列を求める問題です。

ある列 Z が X と Y 両方の部分列であるとき、Z を X とY の共通部分列と言います。例えば、X={a,b,c,b,d,a,b}, Y={b,d,c,a,b,a} とすると、列 {b,c,a} は X と Y の共通部分列です。一方、列 {b,c,a} は X と Y の最長共通部分列ではありません。なぜなら、その長さは 3 であり、長さ 4 の共通部分列 {b,c,b,a} が存在するからです。長さが 5 以上の共通部分列が存在しないので、列 {b,c,b,a} は X と Y の最長共通部分列の1つです。

与えられた2つの文字列 X、Yに対して、最長共通部分列 Z の長さを出力するプログラムを作成してください。与えられる文字列は英文字のみで構成されています。

入力

複数のデータセットが与えられます。最初の行にデータセットの数 q が与えられます。続く 2×q 行にデータセットが与えられます。各データセットでは2つの文字列 X, Y がそれぞれ1行に与えられます。

出力

各データセットについて X, Y の最長共通部分列 Z の長さを1行に出力してください。

制約

1≤q≤150

1≤X,Yの長さ≤1,000

X または Y の長さが 100 を超えるデータセットが含まれる場合、q は 20 以下である。

入力例 1

3

abcbdab

bdcaba

abc

abc

abc

bc

出力例 1

4

3

2

参考文献

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

解题思路:

本题是一个裸的LCS,动态转移方程如下

当s1[i−1]==s2[j−1] 时 dp[i][j]=dp[i−1][j−1]+1

否则dp[i][j]=max(dp[i−1][j],dp[i][j−1])

i和j表示序列一的前i个字符和序列二的前j个字符的最长公共子序列的长度为dp[i][j]

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn = 1050;

char s1[maxn],s2[maxn];
int f[maxn][maxn];

int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s%s",s1,s2);
int len1 = strlen(s1);
int len2 = strlen(s2);
memset(f,0,sizeof(f));
for(int i = 0;i <= len1; i++)
{
for(int j = 0;j <= len2; j++)
{
if(i == 0 || j == 0)f[i][j] = 0;
else
{
if(s1[i-1] == s2[j-1])f[i][j] = f[i-1][j-1] + 1;
else f[i][j] = max(f[i-1][j],f[i][j-1]);
}
}
}
printf("%d\n",f[len1][len2]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: