《动态规划》之--字符串比较问题(扩展距离)
2010-05-23 22:56
239 查看
问题:
对于长度相同的2个字符串A和B,其距离定义为相应位置字符距离之和。2个非空格字符的距离是它们的ASCII码之差的绝对值;空格与空格的距离为0,空格与其他字符的距离为一个定值k。在一般情况下,字符串A和B的长度不一定相同。字符串A的扩展是在A中插入若干空格字符所产生的字符串。在字符串A和B的所有长度相同的扩展中,有一对距离最短的扩展,该距离称为字符串A和B的扩展距离。对于给定的字符串A和B,设计一个算法,计算其扩展距离。
测试数据:
输入:cmc snmn 2 (分别表示字符串A、B和定值k)
输出:10
解答:
设字符串A和B的字串A[1...i]和B[1...j]的扩展距离是val(i, j);
依题意,字符串A和B有三种可能的情况:
1)A串最后一个字符是空格,B串最后一个字符是字母,则val(i, j) = val(i-1, j) + k;
2)A串最后一个字符时字母,B串最后一个字符时空格,则val(i, j) = val(i, j-1) + k;
3)A串和B串最后一个字符均是字母,则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) + k,val(i-1, j-1) + dist(ai , bi) }
(使用动态规划算法,自底向上的计算各个子问题并利用每次计算的结果,避免重复运算,从而降低算法复杂度。)
从动态规划递归式可知,算法的时间复杂度为O(mn),m和n分别是字符串A和B的长度。
代码如下:
#include <iostream>
#include <cmath>
#define MAX 100000 //标识最大的可能整数
int val[300][300];
std::string stra; //字符串A
std::string strb; //字符串B
int k; //定值k
//返回字符a与b的ASCII码的差的绝对值
int dist(char a, char b)
{
return abs(a-b);
}
int comp()
{
int len1, len2;
int tmp;
val[0][0] = 0;
len1 = stra.length();
len2 = strb.length();
for(int i=0; i<=len1; i++) //字符串A和B的有效下标是º1~len,下标0表示空字符串
{ //i或j是0表示A或B串为空串
for(int j=0; j<=len2; j++)
{
if(i+j)//i和j至少一个大于0
{
val[i][j] = MAX;
tmp = val[i-1][j] + k;
if(i && (tmp<val[i][j]))//i大于0
val[i][j] = tmp;
tmp = val[i][j-1]+k;
if(j && (tmp<val[i][j]))//j大于0
val[i][j] = tmp;
tmp = val[i-1][j-1] + dist(stra[i], strb[j]);
if((i*j) && (tmp<val[i][j])) //i和j至少有一个不为0
val[i][j] = tmp;
}
}
}
return val[len1][len2];
}
int main()
{
std::cin>>stra>>strb>>k;
stra = " " + stra; //此处在字符串开头添加一个空格,是为了使字符串stra
strb = " " + strb; //的控制台输入的有效字符下标从1到stra.length()
std::cout<<comp()<<std::endl;
system("pause");
return 0;
}
对于长度相同的2个字符串A和B,其距离定义为相应位置字符距离之和。2个非空格字符的距离是它们的ASCII码之差的绝对值;空格与空格的距离为0,空格与其他字符的距离为一个定值k。在一般情况下,字符串A和B的长度不一定相同。字符串A的扩展是在A中插入若干空格字符所产生的字符串。在字符串A和B的所有长度相同的扩展中,有一对距离最短的扩展,该距离称为字符串A和B的扩展距离。对于给定的字符串A和B,设计一个算法,计算其扩展距离。
测试数据:
输入:cmc snmn 2 (分别表示字符串A、B和定值k)
输出:10
解答:
设字符串A和B的字串A[1...i]和B[1...j]的扩展距离是val(i, j);
依题意,字符串A和B有三种可能的情况:
1)A串最后一个字符是空格,B串最后一个字符是字母,则val(i, j) = val(i-1, j) + k;
2)A串最后一个字符时字母,B串最后一个字符时空格,则val(i, j) = val(i, j-1) + k;
3)A串和B串最后一个字符均是字母,则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) + k,val(i-1, j-1) + dist(ai , bi) }
(使用动态规划算法,自底向上的计算各个子问题并利用每次计算的结果,避免重复运算,从而降低算法复杂度。)
从动态规划递归式可知,算法的时间复杂度为O(mn),m和n分别是字符串A和B的长度。
代码如下:
#include <iostream>
#include <cmath>
#define MAX 100000 //标识最大的可能整数
int val[300][300];
std::string stra; //字符串A
std::string strb; //字符串B
int k; //定值k
//返回字符a与b的ASCII码的差的绝对值
int dist(char a, char b)
{
return abs(a-b);
}
int comp()
{
int len1, len2;
int tmp;
val[0][0] = 0;
len1 = stra.length();
len2 = strb.length();
for(int i=0; i<=len1; i++) //字符串A和B的有效下标是º1~len,下标0表示空字符串
{ //i或j是0表示A或B串为空串
for(int j=0; j<=len2; j++)
{
if(i+j)//i和j至少一个大于0
{
val[i][j] = MAX;
tmp = val[i-1][j] + k;
if(i && (tmp<val[i][j]))//i大于0
val[i][j] = tmp;
tmp = val[i][j-1]+k;
if(j && (tmp<val[i][j]))//j大于0
val[i][j] = tmp;
tmp = val[i-1][j-1] + dist(stra[i], strb[j]);
if((i*j) && (tmp<val[i][j])) //i和j至少有一个不为0
val[i][j] = tmp;
}
}
}
return val[len1][len2];
}
int main()
{
std::cin>>stra>>strb>>k;
stra = " " + stra; //此处在字符串开头添加一个空格,是为了使字符串stra
strb = " " + strb; //的控制台输入的有效字符下标从1到stra.length()
std::cout<<comp()<<std::endl;
system("pause");
return 0;
}
相关文章推荐
- 《动态规划》之--字符串比较问题(扩展距离)
- 字符串A和B的扩展距离,简单dp(动态规划)
- 字符串扩展距离问题
- Mybatis的if test字符串比较问题
- js中的字符串数字比较问题
- 字符串问题---数组中两个字符串的最小距离
- 问题 D: C语言习题 字符串比较
- Java中比较两个字符串是否相等的问题
- 在论坛中出现的比较难的sql问题:12(递归问题2 拆分字符串)
- 字符串比较strcmp()实现及常见问题
- C#字符串数组排序 C#排序算法大全 C#字符串比较方法 一个.NET通用JSON解析/构建类的实现(c#) C#处理Json文件 asp.net使用Jquery+iframe传值问题
- java--动态规划--编辑距离问题
- Mysql等数据库对于版本号类型字符串的比较问题的思考
- .net(关于字符串的相等问题[比较重要])
- 南邮 OJ 1239 字符串比较问题
- 字符串编辑距离问题
- SQLite在字符串比较中的大小写问题
- |NOIOJ|动态规划|2988:计算字符串距离
- 在论坛中出现的比较难的sql问题:1(字符串分拆+行转列问题)
- PHP扩展:zend_parse_parameters() 获取字符串的问题