簡體   English   中英

C++ 中的遞歸子串反轉

[英]Recursive Substring Reversal in C++

我不明白為什么下面的代碼對此不起作用。 該程序的任務是基於兩個索引遞歸地反轉字符串的一部分。 對於遞歸的基本情況,我嘗試了許多使用 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;
}

我假設您想完全反轉字符串,例如:

recurseReverse("abcde", 0, 4) => "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() ,因為如果開始或結束在字符串的長度之外(例如您傳入 -1 或 26),它將拋出.at()

我假設遞歸被指定為分配的一部分,但在這里似乎是一個糟糕的選擇。 如果您的子字符串長度為一百萬個字符,則程序需要跟蹤一百萬個函數調用——這很可能會導致堆棧溢出 在我看來,簡陋的 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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM