实验名称
实现题3-17 字符距离问题。
实验目的
实现题3-17 字符距离问题。
实验原理
使用动态规划算法,根据不同的输入用例,能准确的输出用例中的最短扩展距离,并计算出程序运行所需要的时间。
假设串A1,B1具有最短距离,那么A1[0],B1[0]只有如下三种情况:
Case 1 Case 2 Case 3
A A1[0] ____ A1[0]
B ____ B1[0] B1[0]
每种情况我们需要求出后继子串的最短距离加上当前字符的距离,就得倒最短距离。
实验步骤
① 数据初始化,输入两个字符串以及定值k,设字符串A和B的字串A[1…i]和B[1…j]的扩展距离是val(i, j);
② 依题意,字符串A和B有三种可能的情况:
1)i 和空格匹配。则val(i, j) = val(i-1, j) + k;
2)j 和空格匹配。则val(i, j) = val(i, j-1) + k;
3)扩展距离val(i-1,j-1)加上 i,j 的字符距离。则val(i, j) = val(i-1, j-1) + dist(ai , bi);
由上可知,val(i, j)具有最优子结构性质,且满足如下递推式:
val(i, j) = min{ val(i-1, j) + k,val(i, j-1) + k,val(i-1, j-1) + dist(ai , bi) }
时间复杂度分析
从动态规划递归式可知,算法的时间复杂度为O(mn),m和n分别是字符串A和B的长度。
实验心得
通过这次实验,我巩固了动态规划算法的知识。
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <ctime>
using namespace std;
#define MAX 100000 //标识最大的可能整数
int val[300][300]; //用来存储中间值
string strA; //字符串A
string strB; //字符串B
int k; //定值k
//返回字符a与b的ASCII码的差的绝对值
int dist(char a, char b)
{
return abs(a-b);
}
int comp()
{
val[0][0] = 0;
int tmp;
int len1 = strA.length();
int len2 = strB.length();
for(int i=0; i<=len1; i++) //字符串A和B的有效下标是1~len
for(int j=0; j<=len2; j++) //i或j是0表示A或B串为空串
{
if(i+j)//i和j至少一个大于0
{
val[i][j] = MAX; //初始化值
tmp = val[i-1][j] + k; //情况1)
if(i && (tmp<val[i][j])) //i大于0
val[i][j] = tmp;
tmp = val[i][j-1]+k; //情况2)
if(j && (tmp<val[i][j])) //j大于0
val[i][j] = tmp;
tmp = val[i-1][j-1] + dist(strA[i], strB[j]); //情况3)
if((i*j) && (tmp<val[i][j])) //i和j不为0
val[i][j] = tmp;
}
}
return val[len1][len2];
}
int main()
{
ifstream f("input.txt");
f>>strA>>strB>>k;
f.close();
strA = " " + strA; //此处在字符串开头添加一个空格,是为了使字符串str
strB = " " + strB; //输入的有效字符下标从1到str.length()
clock_t start,end;
start=clock();
cout<<comp()<<endl;
end=clock();
printf("时间:%fms\n",(double)(end-start)/CLK_TCK);
return 0;
}
#include<stdlib.h>
#include<time.h>
#include<fstream>
#include<iostream>
using namespace std;
int main()
{
int n,m;
cin>>n;
m=n;
ofstream out("input.txt");
srand((unsigned)time(NULL));
n=n+rand()%10;
for(int i=0;i<n;i++)
{
char x='a'+rand()%26;
out<<x;
}
out<<'\n';
m=m+rand()%10;
for(int i=0;i<m;i++)
{
char x='a'+rand()%26;
out<<x;
}
out<<'\n';
int k=rand()%5+1;
out<<k;
out.close();
return 0;
}