想得知最长公共子列的长度,应该使用减治法,当AB列末尾元素不同时,AB列元素分别减一,继续递归循环,直到遇到终点:AB数列其一为空,代码如下:
#include <bits/stdc++.h>
//递归处理法
using namespace std;
char a[105],b[105];
int longest(int i,int j){
if(i==0||j==0)return 0;
if(a[i-1]==b[j-1]){
i--,j--;
return longest(i,j)+1;
}
else{
return max(longest(i-1,j),longest(i,j-1));
}
}
int main(){
while(~scanf("%s%s",a,b)){
printf("%d\n",longest(strlen(a),strlen(b)));
}
return 0;
}
但这种方法会导致C(长加宽 长/宽)当长=宽时约等于O(2^n)的时间复杂度.
如果提前使用动态规划存储数字列表,复杂度则降至O(m*n).
此时计算方式为从左上至右下
#include <bits/stdc++.h>
//递归处理法
using namespace std;
char a[105],b[105];
int ab[105][105];
void printphoto(){//图像生成函数,提交请修改
int ia=strlen(a+1)+1,jb=strlen(b+1)+1;
cout<<" ";
for(int k=0;k<=ia;k++)cout<<" "<<a[k]<<" ";
cout<<endl;
for(int h=0;h<jb;h++){
cout<<b[h]<<" ";
for(int k=0;k<ia;k++){
printf("%2d ",ab[k][h]) ;
// cout<<ab[k][h]<<" ";
}
cout<<endl;
}
}
void init(){
int ia=strlen(a+1),jb=strlen(b+1);
for(int h=1;h<=jb;h++){
for(int k=1;k<=ia;k++){
a[k]==b[h]?
ab[k][h]=ab[k-1][h-1]+1
:
ab[k][h] = max(ab[k][h - 1], ab[k - 1][h]);
}
}
printf("%d\n",ab[ia][jb]);
}
int main(){
while(~scanf("%s%s",a+1,b+1)){
init();
printphoto();
}
return 0;
}