当前位置:   article > 正文

精选算法题(4)——字符串比较_比较字符串,abcdefg和25abdfg

比较字符串,abcdefg和25abdfg

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

题目描述:

好久没做题目了,近期刷抖音碰到一个题目,乍一看不是很难,但是手生了,就写个玩玩,大家轻喷。

两个字符串比较,如abcdefg和25abdfxx,返回:位置0多出:25;位置2缺少:c;位置4缺少:e;位置6错误,应为g。

解题思路:

我看很多人说双指针法、动态规划能解,我暂时没想那么多,就用了简单的双循环+滑动窗口。

  1. 取idx1和idx2作为滑动窗口起点。以字符串1为基准,遍历字符串2寻找相同的字符。
  2. 当两个字符一致时,判断下j和idx2的大小情况,如果j大且i和idx1一致,说明字符串2相同字符前面有一段字符是多出的。之后,将idx1加1,再使idx2等于j+1,这样可以使两个字符串的滑动窗口从相同字符后的一个位置开始。
  3. 如果i大于idx1,且j和idx2一致,同理,说明字符串1相同字符前面缺少了一段字符。之后,idx2加1,idx1等于i+1即可。
  4. 如果i大于idx1,j也大于idx2,说明两个字符串相同字符前,各有一段不相同字符,即匹配错误。
  5. 若上述三个条件都不满足,那就说明碰到了连续相同字符串。令idx1和idx2都加1,跳过即可。
  6. 如果i走到最后都没找到匹配对象,则从idx1到字符串1结尾所有字符都匹配失败了。

测试代码:

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. void compareStrings(std::string str1, std::string str2) {
  5. int len1 = str1.length();
  6. int len2 = str2.length();
  7. int idx1 = 0;
  8. int idx2 = 0;
  9. for (int i = 0; i < len1; ++i) {
  10. for (int j = idx2; j < len2; ++j) {
  11. if (str1[i] == str2[j]) {
  12. if (j > idx2 && i == idx1) {
  13. cout << "位置" << i << "多出:" << str2.substr(idx2, j - idx2) << endl;
  14. idx1++;
  15. idx2 = j + 1;
  16. }
  17. else if (i > idx1 && j == idx2) {
  18. cout << "位置" << idx1 << "缺少:" << str1.substr(idx1, i - idx1) << endl;
  19. idx1 = i + 1;
  20. idx2++;
  21. }
  22. else if (i > idx1 && j > idx2) {
  23. cout << "位置" << idx1 << "错误,应为:" << str1.substr(idx1, i - idx1) << endl;
  24. idx1 = i + 1;
  25. idx2= j + 1;
  26. }
  27. else{
  28. idx1++;
  29. idx2++;
  30. }
  31. break;
  32. }
  33. }
  34. if (i == (len1 - 1) && (idx1 < len1)) {
  35. cout << "位置" << idx1 << "错误,应为:" << str1.substr(idx1, i - idx1 + 1) << endl;
  36. }
  37. }
  38. }
  39. int main() {
  40. std::string str1 = "abcdefg";
  41. std::string str2 = "25abdfxx";
  42. cout << "字符串1:" << str1 << endl;
  43. cout << "字符串2:" << str2 << endl;
  44. compareStrings(str1, str2);
  45. return 0;
  46. }

测试结果:

字符串如题目要求时,结果如下,可以发现是满足的。

加几个字符再试试,依然可行。

中间内容再打乱一些,暂无问题。

多几个重复字符,按照我的逻辑,输出结果是对的,但不知道题目是不是这意思。

       如果代码有什么需要改进的或者有什么bug,欢迎评论留言,我会及时更正以免误导他人~

       如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!


       有朋友提出了问题,所以我对算法进行了改进。

  1. 基于动态规划表获取两个字符串的最长非连续重复子串。
  2. 用子串作为参照物,逐一字符遍历。取两个字符串在该字符前的字符串比较,根据不同情况做出不同反馈,具体参见代码和注释。

测试代码:

  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <math.h>
  5. #include <algorithm>
  6. using namespace std;
  7. // 获取最长重复子串(可不连续)
  8. string getSubString(std::string str1, std::string str2) {
  9. int len1 = int(str1.length());
  10. int len2 = int(str2.length());
  11. // 动态规划
  12. vector<vector<int>> m(len1 + 1, vector<int>(len2 + 1, 0));
  13. vector<vector<string>> s(len1 + 1, vector<string>(len2 + 1, ""));
  14. for (int i = 1; i <= len1; ++i){
  15. for (int j = 1; j <= len2; ++j){
  16. if (str1[i - 1] == str2[j - 1]){
  17. m[i][j] = m[i - 1][j - 1] + 1;
  18. s[i][j] = s[i - 1][j - 1] + str1[i - 1];
  19. }
  20. else{
  21. if (m[i - 1][j] > m[i][j - 1]){
  22. m[i][j] = m[i - 1][j];
  23. s[i][j] = s[i - 1][j];
  24. }
  25. else{
  26. m[i][j] = m[i][j - 1];
  27. s[i][j] = s[i][j - 1];
  28. }
  29. }
  30. }
  31. }
  32. return s[len1][len2];
  33. }
  34. // 比较字符串
  35. void compareString(string str1, string str2, string substr) {
  36. int len1 = int(str1.length());
  37. int len2 = int(str2.length());
  38. int len3 = int(substr.length());
  39. // 以重复子串字符遍历
  40. // 若截止到第一个重复字符,t1空,t2有,那就是多出;t1有,t2空,那就是缺少。
  41. // 两个都空说明连续重复字符;若两个都不空,则说明错误。
  42. // 缺少和错误的状态按位置挨个字符输出。
  43. int idx1 = 0;
  44. int idx2 = 0;
  45. for (int i = 0; i < len3; ++i) {
  46. string t1, t2;
  47. int idx3 = idx1;
  48. int idx4 = idx2;
  49. // t1为字符串1在当前重复字符前的字符串
  50. for (int m = idx1; m < len1; ++m) {
  51. if (str1[m] == substr[i]) {
  52. t1 = str1.substr(idx1, m - idx1);
  53. idx1 = m + 1;
  54. break;
  55. }
  56. }
  57. // t2为字符串2在当前重复字符前的字符串
  58. for (int n = idx2; n < len2; ++n) {
  59. if (str2[n] == substr[i]) {
  60. t2 = str2.substr(idx2, n - idx2);
  61. idx2 = n + 1;
  62. break;
  63. }
  64. }
  65. // 根据不同情况处理
  66. if (t1 == "" && t2 != "") {
  67. cout << "位置" << idx3 << "多出:" << t2 << endl;
  68. }
  69. else if (t1 != "" && t2 == "") {
  70. while (t1 != "") {
  71. cout << "位置" << idx3 << "缺少:" << t1[0] << endl;
  72. idx3++;
  73. t1 = t1.substr(1, t1.size() - 1);
  74. }
  75. }
  76. else if (t1 == "" && t2 == "") {
  77. }
  78. else {
  79. while (t1 != "") {
  80. cout << "位置" << idx3 << "错误,应为:" << t1[0] << endl;
  81. idx3++;
  82. t1 = t1.substr(1, t1.size() - 1);
  83. }
  84. }
  85. }
  86. // 对尾巴数据处理
  87. if (idx1 < len1) {
  88. string tail = str1.substr(idx1, len1 - idx1);
  89. while (tail != "") {
  90. cout << "位置" << idx1 << "错误,应为:" << tail[0] << endl;
  91. idx1++;
  92. tail = tail.substr(1, 1);
  93. }
  94. }
  95. }
  96. int main() {
  97. std::string str1 = "1abcdefui";
  98. std::string str2 = "abxcegfui";
  99. cout << "字符串1:" << str1 << endl;
  100. cout << "字符串2:" << str2 << endl;
  101. // 获取最长重复子串(可不连续)
  102. string substr = getSubString(str1, str2);
  103. cout << "substring:" << substr << endl;
  104. // 比较字符串
  105. compareString(str1, str2, substr);
  106. system("pause");
  107. return 0;
  108. }

测试代码:

 

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

闽ICP备14008679号