当前位置:   article > 正文

算法学习015 字符串子串距离 c++动态规划算法实现 中小学算法思维学习 信奥算法解析_字符串距离问题c++

字符串距离问题c++

目录

C++字符串子串距离

一、题目要求

1、编程实现

2、输入输出

二、算法分析

三、程序编写

四、运行结果

五、考点分析

六、推荐资料


C++字符串子串距离

一、题目要求

1、编程实现

      设有字符串X,我们称在串X的头尾及中间插入任意多个空格后构成的新字符串为X的扩展串,如字符串X为“abcdcb”,则字符串“abcd#cb”,“*#a#bcdcb#”和“abcd#cb#”都是X的扩展串,这里“#”代表空格字符。

      如果A1是字符串A的扩展串,B1是字符串B的扩展串,A1和B1具有相同的长度,那么我们定义字符串A1和B1的距离为相应位置上的字符的距离总和,而两个非空格字符的距离定义为它们的ASCII码的差的绝对值,而空格字符与其他任意字符之间的距离为已知的定值K,空格字符与空格字符的距离为0。在字符串A、B的所有扩展串中,必定存在两个等长的扩展串A1、B1,使的A1与B1之间的距离达到最小,我们将这一距离定义为字符串A、B的距离。

     请你写出一个程序,求出字符串A、B的距离

2、输入输出

输入描述:

输入文件第一行为字符串A,

第二行为字符串B。A、B均由小写字母组成且长度均不超过2000。

第三行为一个整数K(1〈=K〈=100),表示空格与其他字符的距离。

输出描述:输出文件仅一行包含一个整数,表示所求的字符串A、B的距离。

输入样例:

  1. cmc
  2. snmn
  3. 2

输出样例:

10

二、算法分析

  1. 从给定题目的初步分析可以看出,这是一个字符串编辑距离的提醒
  2. 所以可以采用动态规划的方式实现
  3. 由于要求的是字符串AB的最小距离,所以可以设置动态数组dp[i][j],i子串A1的字母,j表示子串B1的字母;对应的dp[i][j]就是子串A1的前i个字母到子串B1的前j个字母的最小距离
  4. 而dp[i][j]在我们这道题目中有三种情况:第一种子串A1的第i个字母对应的子串B1的空格,对应的dp[i][j]=dp[i-1][j]+k
  5. 第二种子串B1的第j个字母对应子串A1的空格,对应的dp[i][j]=dp[i][j-1]+k
  6. 第三种子串A1的第i个字母对应的子串B1的第j个字母,对应的dp[i][j]=dp[i-1][j-1]+abs(a[i-i]-b[j-1]);因为第i个对应的数组下标是i-1
  7. 所以可以得出对应的动态数组dp[i][j]的状态转移方为:dp[i][j]=min(dp[i-1][j]+k,dp[i][j-1]+k,dp[i-1][j-1]+abs(a[i-i]-b[j-1]))
  8. dp数组的初始化分以下两种情况进行设置:,dp[i][0]=k*i(A1子串的前i个字符对应B1子串的空格),dp[0][j]=k*j(B1子串的前j个字符对应A1子串的空格)

三、程序编写

  1. #include <bits/stdc++.h>
  2. #include <cmath>
  3. using namespace std;
  4. int dp[2010][2010];
  5. int minDistance(string s1,string s2,int k)
  6. {
  7. int la = s1.length();
  8. int lb = s2.length();
  9. dp[0][0] = 0;
  10. for(int i=0;i<=la;i++)
  11. dp[i][0] = k * i;
  12. for(int j=0;j<=lb;j++)
  13. dp[0][j] = k * j;
  14. for(int i=1;i<=la;i++)
  15. {
  16. for(int j=1;j<=lb;j++)
  17. {
  18. dp[i][j] = min(min(dp[i-1][j]+k,dp[i][j-1]+k),dp[i-1][j-1]+abs(s1[i-1]-s2[j-1]));
  19. }
  20. }
  21. return dp[la][lb];
  22. }
  23. int main()
  24. {
  25. string s1,s2;
  26. cin >> s1 >> s2;
  27. int k;
  28. cin >> k;
  29. cout << minDistance(s1,s2,k);
  30. }

 本文作者:小兔子编程 作者首页:小兔子编程-CSDN博客

四、运行结果

  1. cmc
  2. snmn
  3. 2
  4. 10

五、考点分析

难度级别:难,这题相对而言在于如何确定动态规划的桩体转移方程,具体主要考查如下:

  1. 分析题目,找到解题思路
  2. 充分掌握变量和数组的定义和使用
  3. 学会动态规划算法的原理和使用
  4. 确定动态数组的定义和含义
  5. 分析出动态规划算法的状态转移方程以及遍历顺序
  6. 学会输入流对象cin的使用,从键盘读入相应的数据
  7. 学会for循环的使用,在确定循环次数的时候推荐使用学会
  8. 掌握输出流对象cout的使用,与流插入运算符 << 结合使用将对象输出到终端显示
  9. 学会分析题目,算法分析,将复杂问题模块化,简单化,从中找到相应的解题思路
  10. 充分掌握变量定义和使用、分支语句、循环语句和动态规划算法的应用

PS:方式方法有多种,小朋友们只要能够达到题目要求即可!

六、推荐资料

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/1019454
推荐阅读
相关标签
  

闽ICP备14008679号