您的位置:首页 > 其它

求最大公共子序列的长度

2017-03-26 15:29 218 查看
求两个字符串的最大公共序列的长度,比较简单的思想就是利用动态规划的思想来实现。先直接贴代码:

//求两个字符串的最大公共子序列
int getMaxLength(string str1,string str2){
int len1 = str1.length();
int len2 = str2.length();
int dp[101][101];
for(int i=0;i<len1;i++){
for(int j=0;j<len2;j++){
if(str1[i]==str2[j]){
dp[i+1][j+1] = dp[i][j]+1;
}else{
dp[i+1][j+1] = max(dp[i][j+1] ,dp[i+1][j]);
}
}
}
return dp[len1][len2];
}


在代码中,利用dp数组来记录当前的到当前字符的最大公共子串。

假如:我们给str1赋值为abcd,给str2赋值为adcb。

我们的思想是这样的,先算出字符串a与字符串str2的最大公共子序列,发现a和str2的最大公共子序列为1,于是在a的基础基础上,计算字符串ad与str2的最大公共子序列的长度。以此类推,求出字符串str1与str2的最长子序列。

具体的实现过程结合下图可以比较清晰的看出来:



当str1与str2中的字符相等时,就取上一个dp[i-1][j-1]+1作为当前的最大公共子串的长度,譬如途中的黄色标识的块。如果不想等,就去前面或者上面值的最大值最为当前元素的值。所以,我们可以知道,最后dp[len1][len2]一定是最大的,也是我们所要求的值。

程序运行的结果如图:



运用:

例如下面的题目:

给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?

输出需要删除的字符个数。

输入描述:

输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.

输出描述:

对于每组数据,输出一个整数,代表最少需要删除的字符个数。

输入例子:

abcda

google

输出例子:

2

2

参考ac代码:

#include<iostream>

using namespace std;

//求出最大公共子序列的长度
int getMaxLength(string str){
int dp[1001][1001]={0};
string str2;
int len = str.length();
for(int i=0;i<len;i++){
str2[i]= str[len-i-1];
}

for(int j=0;j<len;j++){
for(int i=0;i<len;i++){
if(str[i]==str2[j]){
dp[i+1][j+1]=dp[i][j]+1;
}else{
dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
}
}
}
return len-dp[len][len];
}

int main(){
string str1;
while(cin>>str1){
cout<<getMaxLength(str1)<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划 dp
相关文章推荐