简体   繁体   English

C++ 中的递归子串反转

[英]Recursive Substring Reversal in C++

I do not understand why the following code does not work for this.我不明白为什么下面的代码对此不起作用。 The task of this program was to reverse a section of a string based on two indices recursively.该程序的任务是基于两个索引递归地反转字符串的一部分。 I have tried many alternate methods using swap() and different start and end conditions for the base case of the recursion.对于递归的基本情况,我尝试了许多使用 swap() 和不同开始和结束条件的替代方法。 I feel really dumb right now and I am waiting for someone to point out the obvious to me.我现在感觉真的很愚蠢,我在等待有人向我指出显而易见的事情。

#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;
}

I assume that you want to fully reverse the string, eg:我假设您想完全反转字符串,例如:

recurseReverse("abcde", 0, 4) => "edcba"

The problem is that you are swapping consecutive elements.问题是您正在交换连续的元素。 So on the first call, you swap round d and e, and then the d forever remains at the end of the string.所以在第一次调用时,你交换了 d 和 e,然后 d 永远留在字符串的末尾。

Instead, you should be swapping the first and last elements of the string, and then moving in from both sides.相反,您应该交换字符串的第一个和最后一个元素,然后从两侧移入。

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;
}

You should use .at() here, because it will throw if start or end are outside the length of the string (eg you passed in -1, or 26).您应该在这里使用.at() ,因为如果开始或结束在字符串的长度之外(例如您传入 -1 或 26),它将抛出.at()

I assume that recursion was specified as part of the assignment, but it seems like a poor choice here.我假设递归被指定为分配的一部分,但在这里似乎是一个糟糕的选择。 If your substring was, say, a million characters long, the program would need to keep track of a million function calls - which would more than likely result in a stack overflow .如果您的子字符串长度为一百万个字符,则程序需要跟踪一百万个函数调用——这很可能会导致堆栈溢出 In my opinion, the humble for loop seems better suited to this task.在我看来,简陋的 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;
}

and if I was writing production code, rather than an assignment, I would just get the STL to do it for me:如果我正在编写生产代码,而不是作业,我只会让 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM