给出两个字符串,通过三种操作:
1,修改一个字符
2,增加一个字符
3,删除一个字符
一次操作,表示两个字符串的距离加1,通过三种操作,使得两个字符串最终相等,求解最少操作数,从而求得两个字符串的相似度,相似度表示为1/(距离 + 1)。比如abcdefg和abcdef距离为1(通过abcdefg删除g一个操作),这样相似度为1/2 = 0.5。
写出程序。
问题分析:
在求解xabcd和xbde字符串的相似度时,由于第一个字符串相等,可以证明,xabcd和xbde的相似度与abcd和bde的相似度相等,这样我们可以将问题缩减为更短的字符串相似度。
如果第一个字符不相等呢?我们可以通过六种方式,让两个字符串的第一个字符相等:
1,删除A串的第一个字符,计算A[2,3 ... ]与B[1,2 ...]的相似度
2,删除B串的第一个字符,计算B[2,3 ... ]与A[1,2 ...]的相似度
3,增加B[1]到A串首,计算原来的A[1,2 ...]与原来的B[2,3 ...]的相似度
4,增加A[1]到B串首,计算原来的B[1,2 ...]与原来的A[2,3 ...]的相似度
5,修改A[1]为B[1],计算原来的A[2,3 ...]与原来的B[2,3 ...]的相似度
5,修改B[1]为A[1],计算原来的A[2,3 ...]与原来的B[2,3 ...]的相似度
这样我们可以采用递归的方法求解字符串的相似度,代码如下:
/*
* bop_3_3.cpp
*
* Created on: 2012-5-24
* Author: ict
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
#define MAX 100
int calculate(char *a, char *b)
{
int l1 = strlen(a);
int l2 = strlen(b);
//递归返回条件,判断字符串A和B的长度是否为0
if(l1 == 0)
{
if(l2 == 0)
return 0;
else
return l2;
}
if(l2 == 0)
{
if(l1 == 0)
return 0;
else
return l1;
}
if(a[0] == b[0]) //a[0] == b[0], we just calculate the a[1,2 ...] and the b[1,2 ...] distance
{
return calculate(a + 1, b + 1);
}
else
{
int t1 = calculate(a+1, b); //just delete the a[0], or just add the a[0] before the b[0]
int t2 = calculate(a, b+1); //just delete the b[0], or just add the b[0] before the a[0]
int t3 = calculate(a+1, b+1); //just change the a[0] to b[0], or change the b[0] to a[0]
return min(min(t1, t2), t3) + 1; //return the minimal value
}
}
int main()
{
char a[MAX];
char b[MAX];
scanf("%s", a); //input the string A
scanf("%s", b); //input the string B
printf("%f\n", 1/(1.0 + calculate(a, b)));
return 0;
}