【问题标题】:Recursive Substring Reversal in C++C ++中的递归子字符串反转
【发布时间】:2020-06-07 04:14:49
【问题描述】:

我不明白为什么下面的代码对此不起作用。该程序的任务是基于两个索引递归地反转字符串的一部分。对于递归的基本情况,我尝试了许多使用 swap() 和不同开始和结束条件的替代方法。我现在真的很愚蠢,我正在等待有人指出对我来说显而易见的事情。

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

string recurseReverse(string str, int start, int end);

int main() {
cout << "Starting string: ";
string alphabet = "abcdefghijklmnopqrstuvwxyz";
cout << alphabet;

cout << "Passing reverse the string along with values 11 and 18 for indices." << endl;
alphabet = recurseReverse(alphabet, 11, 18);
cout << alphabet << endl;

cout << "Passing reverse the string along with values 5 and 23 for indices." << endl;
alphabet = recurseReverse(alphabet, 5, 23);
cout << alphabet << endl;

cout << "Realphebetizing the string." << endl;
sort(alphabet.begin(), alphabet.end());
cout << alphabet << endl;

cout << "Dealphebetizing the string." << endl;
alphabet = recurseReverse(alphabet, 0, 25);
cout << alphabet << endl;

return 0;
}

string recurseReverse(string str, int start, int end) {
char temp = ' ';

if(start < end) {
temp = str[end - 1];
str[end - 1] = str[end];
str[end] = temp;
str = recurseReverse(str, start, end - 1);
}

return str;
}

【问题讨论】:

  • 欢迎来到 Stack Overflow!听起来您可能需要学习如何使用debugger 来单步执行您的代码。使用好的调试器,您可以逐行执行您的程序,并查看它与您期望的偏差在哪里。如果您要进行任何编程,这是必不可少的工具。进一步阅读:How to debug small programs.
  • 您期望发生什么,实际发生了什么?在传入 0 和 15 的情况下,你会期望 z 先出现,a 最后出现吗?

标签: c++ string recursion


【解决方案1】:

我假设你想完全反转字符串,例如:

recurseReverse("abcde", 0, 4) =&gt; "edcba"

问题在于您正在交换连续的元素。所以在第一次调用时,你交换了 d 和 e,然后 d 永远保留在字符串的末尾。

相反,您应该交换字符串的第一个和最后一个元素,然后从两边移入。

string recurseReverse(string str, int start, int end) {

  if(start < end) {
    std::swap(str.at(start), str.at(end));
    str = recurseReverse(str, start + 1, end - 1);
  }

  return str;
}

您应该在此处使用.at(),因为如果 start 或 end 超出字符串长度(例如,您传入 -1 或 26),它将抛出异常。

我假设递归被指定为分配的一部分,但在这里似乎是一个糟糕的选择。例如,如果您的子字符串有一百万个字符长,那么程序将需要跟踪一百万个函数调用——这很可能会导致stack overflow。在我看来,不起眼的 for 循环似乎更适合这项任务。

std::string reverseSubstring(std::string str, size_t start, size_t end) {

for(size_t left = start, right = end; left < right; ++left, --right)
{
    std::swap(str.at(left), str.at(right));
}

return str;
}

如果我正在编写生产代码,而不是作业,我只会让 STL 为我做:

std::string reverseSubstring(std::string str, size_t start, size_t end) {

  if(start >= end || start < 0 || end >= str.size())
  {
    throw std::invalid_argument("start and end must be valid, and start must be before end");
  }
  std::reverse(str.begin() + start, str.begin() + end + 1);

  return str;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-24
    • 2020-07-27
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多