问题描述
- 现在有两个字符串已知
- 要求的他们最长的公共子序列长度
例如csdnblog和belong的最长公共子序列是4,由于它们都含有blog这一个子序列
解题思路与算法思想
既然使用动态规划算法,那么算法的核心就是将问题分布
这一点和数学归纳法有点相似
假设含有字符串xc长度为a
有字符串y长度为b
现在在比较x的前a1位和y的前b1位置的最长公共子序列
那么我们需要假设已知之前的所有状态,如图:
程序模型的建立
- 先将数据输入
- 建立转移方程:
如果当前的两个字符相同
那么加一
如果不同
在其他状态之中选择一个比较大的
- 之后通过递归+记忆的方式计算出匹配的最大字符串
- 最后将匹配的个数输出
数据结构的选用
选用string去储存这两个字符串
程序设计流程
输入数据
进行计算
输出结果
程序设计伪码算法
if((c<0)||(d<0))
{
return 0 ;
}
if(bb[c][d]!=-1)
{
return bb[c][d] ;
}
if(a[c] == b[d] )
{
bb[c][d] = find_num(a,b,c-1,d-1)+1 ;
return bb[c][d] ;
}
else
{
bb[c][d] = max(find_num(a,b,c-1,d),find_num(a,b,c,d-1)) ;
return bb[c][d] ;
}
源程序编码清单
#include<iostream>
#include<string>
#include<vector>
using namespace std ;
int find_num(string a ,string b ,int c ,int d) ;
vector< vector<int> > bb ;
int main(void)
{
string a ;
string b ;
vector<int>aa ;
cin>>a ;
cin>>b ;
for(int i = 0 ;i<b.size() ;i++)
{
aa.push_back(-1) ;
}
for(int i = 0 ;i<a.size() ;i++)
{
bb.push_back(aa) ;
}
printf("%d",find_num(a,b,a.size()-1,b.size()-1)) ;
}
int find_num(string a ,string b ,int c ,int d)
{
if((c<0)||(d<0))
{
return 0 ;
}
if(bb[c][d]!=-1)
{
return bb[c][d] ;
}
if(a[c] == b[d] )
{
bb[c][d] = find_num(a,b,c-1,d-1)+1 ;
return bb[c][d] ;
}
else
{
bb[c][d] = max(find_num(a,b,c-1,d),find_num(a,b,c,d-1)) ;
return bb[c][d] ;
}
}
程序输入、输出
输入:
csdnblog
belong
输出:
4
输入输出文件,或程序运行结果截图
时间与空间复杂度分析
时间复杂度是n^2
程序使用说明
总结与完善