Попытка перевернуть строку в C ++, но вернуть ту же строку - PullRequest
4 голосов
/ 07 марта 2019

Я получаю ту же строку обратно, когда пытаюсь изменить ее в C ++.

Я прочитал, что рекурсия - это хороший способ изменить ситуацию.Я попытался реализовать рекурсивный алгоритм, возвращая первый символ строки и вызывая ту же функцию с первым удаленным символом, пока строка не будет иметь размер 1. Моя первая функция удаляет первый символ строки, а вторая функция обращает его:

string deleteFirstElement(string input) {

    if (input.size() == 1) {
        return input;
    }

    // This loop brings the first element to the last position
    for (int i = 0; i < input.size()-1; i++) { 
        char temp;
        temp = input.at(i);
        input.at(i) = input.at(i+1);
        input.at(i + 1) = temp;
    }

    input.pop_back();   // Delete last element of the string
    return input;
}

string reverseit(string input) {
    if (input.size() == 1) {
        return input;
    }
    else {
        return input.at(0) + reverseit(deleteFirstElement(input));
    }
}

Но почему я возвращаю одну и ту же строку, а не наоборот?

Ответы [ 4 ]

8 голосов
/ 07 марта 2019

Вы получаете ту же строку обратно, потому что вы строите ту же строку снова. На примере «ABC» вы увидите, что делает функция:

reverseit ("ABC") возвращает 'A' + reverseit ("BC")
reverseit ("BC") возвращает 'B' + reverseit ("C")
reverseit ("C") возвращает 'C'

Вы бы хотели

char firstChar = input.at(0);
return  reverseit(deleteFirstElement(input)) + firstChar;

Но на самом деле вы должны искать другое решение. Рекурсия

  • уменьшает читабельность
  • медленно
  • использует много стековой памяти
  • легко создает трудные для отладки бесконечные циклы

в общем, следует избегать, если это возможно. Конечно, некоторые решения действительно элегантны, но циклы почти всегда быстрее.

3 голосов
/ 07 марта 2019

измените остальную часть с этого

  string reverseit(string input) {
        if (input.size() == 1) {
            return input;
        }
        else {
            return input.at(0) + reverseit(deleteFirstElement(input));
        }
    }

на этот

string reverseit(string input) {
    if (input.size() == 1) {
        return input;
    }
    else {
        return reverseit(deleteFirstElement(input))+ input.at(0);
    }
}
2 голосов
/ 07 марта 2019

Рекурсия - не простой способ изменить ситуацию.

Вот простой способ:

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

int main()
{
    string s { "hello" };

    reverse(s.begin(), s.end());

    cout << s << endl;
}

Вот рекурсивное решение. Это работает, но гораздо менее разумно и эффективно.

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

string recursiveReverse(string value, string accum = "")
{
    if(value.size() == 0)
    {
        return accum;
    }
    else
    {
        accum += value.back();
        value.pop_back();
        return recursiveReverse(value, accum);
    }
}

int main()
{
    string s { "hello" };

    s = recursiveReverse(s);

    cout << s << endl;
}
1 голос
/ 07 марта 2019

Если у вас есть , эта проблема сводится к следующему:

string reverseit(string input) {
  string result(input);
  boost::range::reverse(result);
  return result;
}

Без , вы можете вместо этого использовать:

std::reverse(result.begin(), result.end());

Как уже отмечалось, рекурсия снижает читабельность вашей программы и должна быть зарезервирована для редких случаев (обычно там, где другое решение более сложное).

...