目的:字符串是一种基础且广泛使用的数据结构,与字符串相关的题目既可以考察基本程序设计能力和技巧,也可以考查较强算法设计能力。
要求:设有字符串X,称在X的头尾及中间插入任意多个空格后构成的新字符串为X的扩展串,如字符串X为“abcbcd”,则字符串“abcb□cd”,“□a□bcbcd□”和“abcb□cd□”都是X的扩展串,这里“□”代表空格字符。 如果A1是字符串A的扩展串,B1是字符串B的扩展串,A1与B1具有相同的长度,那么定义字符串A1与B1的距离为相应位置上的字符的距离总和,而两个非空格字符的距离定义为它们的ASCII码的差的绝对值,而空格字符与其它任意字符之间的距离为已知的定值K,空格字符与空格字符的距离为0。在字符串A、B的所有扩展串中,必定存在两个等长的扩展串A1、B1,使得A1与B1之间的距离达到最小,将这一距离定义为字符串A、B的距离。请编写程序,求出字符串A、B的距离。
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
const int N = 2005;
char S[N], T[N];
int dp[N][N];
//动态规划问题
int Work(char *S, char *T, int k)
{
int n = strlen(S);
int m = strlen(T);
dp[0][0] = 0;
for (int i = 1; i <= n; i++)
dp[i][0] = i * k;
for (int i = 1; i <= m; i++)
dp[0][i] = i * k;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
dp[i][j] = min(dp[i - 1][j - 1] + abs(S[i - 1] - T[j - 1]), min(dp[i - 1][j], dp[i][j - 1]) + k);
//此处就是动态规划,去除了递归中重复计算的高时间复杂度,分为3种情况
return dp[n][m];
}
//递归求解
int Distance(char *S, char *T, int k) {
int ret, temp[3];
if (*S == '\0' && *T == '\0') return 0;
if (*S == '\0' && *T != '\0') return k*strlen(T);
if (*S != '\0' && *T == '\0') return k*strlen(S);
temp[0] = Distance(S + 1, T,k) + k;
temp[1] = Distance(S , T+1, k) + k;
temp[2] = Distance(S + 1, T + 1, k) + abs(*S - *T);
ret = min(temp[0], min(temp[1],temp[2]));
return ret;
}
int main()
{
int k;
cout << "请输入第一个字符串数组:";
cin >> S;
cout << "请输入第二个字符串数组:";
cin >> T;
cout << "请输入固定的K值:";
cin >> k;
cout << Work(S, T, k) << endl;
cout << Distance(S, T, k) << endl;
system("pause");
return 0;
}