/*
题目:
设有字符串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的距离。
*/
给出最优子结构:
函数D()为两个字符或字符串的距离
函数L()为字符串的长度
K为空格字符与非空格字符的长度
D(str1,str2) =
L(str1)*K 当str1非空串,str2空串
L(str2)*K 当str2非空串,str1空串
min(D(str1[1],str2[1])+D(str1[2...n],str2[2...n]), K+D(str1,str2[2...n]), K+D(str1[2...n],str2))
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "math.h"
#define K 2/*空格与其他字符的距离*/
char A[101];/*字串A*/
char B[101];/*字串B*/
char extendA[201];/*字串A的扩展串*/
char extendB[201];/*字串B的扩展串*/
int distance[101][101];/*记录字串的距离*/
int construct[101][101];/*用于构造A,B的扩展字符串*/
/*比较三个数的大小,返回最小那个数的下标(从0开始)*/
int GetMinIndex (int a, int b, int c)
{
if (a < b)
{
if (c < a)
return 2;
else
return 0;
}
else/*b<=a*/
{
if (c < b)
return 2;
else
return 1;
}
}
/*按照规则返回两个字符的距离*/
int GetCharDistance (char a, char b)
{
if ((a==32&&b!=32) || (a!=32&&b==32))
return K;
else
return abs(a-b);
}
/*求解并打印两个字符串的距离*/
void GetStrDistance (char* A, char* B)
{
int i, j, p, temp[3], minIndex, dir;
int m = strlen(A);
int n = strlen(B);
/*初始化*/
for (i=0; i<=m; i++)
distance[i][0] = i*K;
for (j=0; j<=n; j++)
distance[0][j] = j*K;
extendA[200] = '/0';
extendB[200] = '/0';
/*自底向上求解*/
for (i=1; i<=m; i++)
for (j=1; j<=n; j++)
{
/*注意字符串的下标和表格的下标*/
temp[0] = GetCharDistance(A[i-1], B[j-1]) + distance[i-1][j-1];
temp[1] = GetCharDistance(A[i-1], ' ') + distance[i-1][j];
temp[2] = GetCharDistance(' ', B[j-1]) + distance[i][j-1];
construct[i][j] = minIndex = GetMinIndex(temp[0], temp[1], temp[2]);
distance[i][j] = temp[minIndex];
}
/*从后往前构造扩展字符串*/
i = m;;
j = n;
p = 199;
while (i>0 || j>0)
{
dir = construct[i][j];
if (dir == 0)
{
extendA[p] = A[--i];
extendB[p] = B[--j];
}
else if (dir == 1)
{
extendA[p] = A[--i];
extendB[p] = ' ';
}
else
{
extendA[p] = ' ';
extendB[p] = B[--j];
}
p--;
}
/*移动字符串*/
for (i=0; i<200-p; i++)
{
extendA[i] = extendA[i+p+1];
extendB[i] = extendB[i+p+1];
}
/*打印距离与A,B的扩展字串*/
printf("The distance of %s and %s is %d/n", A, B, distance[m][n]);
printf("The extend-string of A is:");
for (i=0; i<200-p-1; i++)
printf("%c",extendA[i]);
printf("/n");
printf("The extend-string of B is:");
for (i=0; i<200-p-1; i++)
printf("%c",extendB[i]);
}
int main ()
{
printf("Please input the two strings the length of which are shorter than 101:/n");
printf("String A is: ");
scanf("%s", A);
printf("String B is: ");
scanf("%s", B);
GetStrDistance(A, B);
system("pause");
return 0;
}