求两个字符串的最大公共序列的长度,比较简单的思想就是利用动态规划的思想来实现。先直接贴代码:
//求两个字符串的最大公共子序列
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输出例子:
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;
}
}