0
#include <iostream>
#include <string>
using namespace std;
void ReverseString(string &S, int size)
{
    static int start = 0;
    if (start == size - 1 || start == size)
    {
        return;
    }
    else
    {
        swap(S[start++], S[size - 1]);
        ReverseString(S, size - 1);
    }
}
int main()
{
    cout << "enter a string to reverse" << endl;
    string s;
    getline(cin, s);
    cout << "Before Reversing" << endl;
    cout << s << endl;
    ReverseString(s, s.size());
    cout << "After Reversing" << endl;
    cout << s << endl;
    return 0;
}

I am trying to nail recursions as much as i can,and i was trying to reverse a string using recursion i didn't know how to do it at first,tried many different ways to do it,but i saw code samples on string reversing,but none of it made sense to me,so i made my own one,but not quite sure of it,i'm just asking for opinion,is it clean and functional??

Thank You

3
  • 2
    Welcome to Stack Overflow! If you want help improving working code, you should post this on CodeReview.SE. If you do decide to do so, please delete the question here. Commented Mar 17, 2020 at 18:35
  • If you are not asking for a review of working code, then please explain how it misbhaves. Also saying multiple times "I tried lots. I read lots." does not really mean that you are demonstrating research effort, as long as you do not show what you tried or list and discuss what you read. So your question lacks details and focus. Commented Mar 17, 2020 at 18:39
  • "i'm just asking for opinion" consider Nathan's comment. Stack Overflow is not designed for opinions. Commented Mar 17, 2020 at 18:45

6 Answers 6

4

Using a function local static variable in a recursive function is a bad idea. Recursive functions should get all their state as input arguments.

Here's a simplified version that divides the logic into two functions.

void ReverseString(string &S, int start, int end)
{
   if ( start < end )
   {
      swap(S[start], S[end - 1]);
      ReverseString(S, start+1, end - 1);
   }
}

void ReverseString(string &S)
{
   ReverseString(S, 0, S.size());
}

Most of the time, higher level functions would only call the second function. The first function can be called from a higher level function if there is a need to reverse only a subset of a string.

Here's a sample program

#include <iostream>
#include <string>

using namespace std;

void ReverseString(string &S, int start, int end)
{
   if ( start < end )
   {
      swap(S[start], S[end - 1]);
      ReverseString(S, start+1, end - 1);
   }
}

void ReverseString(string &S)
{
   ReverseString(S, 0, S.size());
}

int main()
{
    string s = "The string to reverse" ;

    cout << "Before Reversing" << endl;
    cout << s << endl;

    ReverseString(s);
    cout << "After Reversing" << endl;
    cout << s << endl;

    ReverseString(s, 0, 7);
    cout << "After Reversing a subset" << endl;
    cout << s << endl;
    return 0;
}

and its output

Before Reversing
The string to reverse
After Reversing
esrever ot gnirts ehT
After Reversing a subset
reverse ot gnirts ehT

See it working at https://ideone.com/9nMlsP.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you,so now i understood that i shouldn't use stack variables in recursive functions but i didn't understand why,can you clarify a little bit more? Regards
3

is it ... functional??

If by "functional" you mean "does it work", then you tell me.

If you mean "functional" as in "functional" programming style, then no it isn't. In functional style, you don't modify arguments in place, but instead return a new value. Also relying on global state (i.e. static objects) is very anti-functional.

Here is an example:

std::string
ReverseString(std::string_view sv)
{
    if (sv.empty())
        return "";
    std::string_view x  = sv.substr(0, 1)
    std::string_view xs = sv.substr(1);
    return ReverseString(xs) + x;
}

// usage
s = ReverseString(s);

In future, if Pattern matching was introduced to the language, then it could potentially be written like this:

std::string
ReverseString(std::string_view sv)
{
    inspect(sv) {
        "":      return "";
        [x:xs]:  return ReverseString(xs) + x;
    }
}

However, the current proposal does not suggest introducing support for matching ranges like this, so this is highly theoretical.

2 Comments

Note to OP, this is an extremely bad idea in production grade code if you don't control string length. And even if you, in the absence of tail-call optimization the iterative version will be lightning fast.
To expand on @TanveerBadar's comment: Also note that implementing any linear algorithm with recursion is a bad idea in production code unless you write in a functional language that guarantees tail call optimisation (i.e. converts the function into an iterative version behind your back)
0

Local static variables are dangerous. Since their state will remain between function calls. In my approach i used slen as the length of a string and the currentIndex as the last swapped index on the string. Since it is enough to swap till the middle of the string, finish case is when (currentIndex == slen/2). I also added some test cases as an example.(even length, odd length, zero case and palindrome)

#include <iostream>
#include <string>
using namespace std;
void ReverseString(string &S, int currentIndex, int slen)
{
    if (slen / 2 == currentIndex) return;

    swap(S[currentIndex], S[slen - 1 - currentIndex]);
    currentIndex++;

    ReverseString(S, currentIndex, slen);
}

void testReverseString() {
    string s = ""; 
    ReverseString(s, 0, s.length());
    assert(s == "");

    s = "ahmet"; 
    ReverseString(s, 0, s.length());
    assert(s == "temha");

    s = "ahaha"; 
    ReverseString(s, 0, s.length());
    assert(s == "ahaha");

    s = "haha"; 
    ReverseString(s, 0, s.length());
    assert(s == "ahah");
}

int main()
{
    testReverseString();
    return 0;
}

Comments

0

Your function with a static variable can be called only once because after its recursive calls the static variable start will not be equal to 0 as it is required. So the function is not "functional".

Here is a demonstrative program that shows how the function can be written with using a static variable and without using a static variable.

#include <iostream>
#include <string>
#include <utility>

void ReverseString1( std::string &s )
{
    static std::string::size_type i = 0;

    if ( not ( s.size() - 2 * i < 2 ) )
    {
        std::swap( s[i], s[s.size() - i - 1] );

        ++i;
        ReverseString1( s );
        --i;
    }
}

void ReverseString2( std::string &s, std::string::size_type pos = 0 )
{
    if ( not ( s.size() - 2 * pos < 2 ) )
    {
        std::swap( s[pos], s[s.size() - pos - 1] );
        ReverseString2( s, pos + 1 );
    }
}

int main() 
{
    std::string s( "Hello World!" );

    std::cout << s << '\n';

    ReverseString1( s );

    std::cout << s << '\n';

    ReverseString2( s );

    std::cout << s << '\n';

    return 0;
}

The program output is

Hello World!
!dlroW olleH
Hello World!

Comments

0

Anyone can reverse a string one char at a time, but much cooler is to reverse each third of the string and swap the outer thirds. This cuts stack depth as well as sowing confusion amongst the competition. Note that max stack depth of recursion per character is N, whereas this is cube root of N.

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

void ReverseRegion(string &s, int start, int sz)
{
  // regions < 2 need no action
  if (sz == 2) {
    char tmp = s[start];
    s[start] = s[start+1];
    s[start+1] = tmp;
  } else if (sz > 2) {
    int s3 = sz/3;
    ReverseRegion(s, start, s3);
    string tmp = s.substr(0,start) + s.substr(start+sz-s3,s3) + s.substr(start+s3, sz-2*s3) + s.substr(start,s3) + s.substr(start+sz);
    // cout << "do: " << tmp << "\n";
    s = tmp;
    ReverseRegion(s, start+s3, sz-2*s3);
    ReverseRegion(s, start, s3);
  }
}


void ReverseString(string &S)
{
  ReverseRegion(S, 0, S.size());
}

int main()
{
    cout << "enter a string to reverse" << endl;
    string s;
    getline(cin, s);
    cout << "Before Reversing" << endl;
    cout << s << endl;
    ReverseString(s);
    cout << "After Reversing" << endl;
    cout << s << endl;
    return 0;
}

Comments

-1

This program can reverse anything... Using recursion and that's all.

#include<iostream>
using namespace std;
int main(){
    char c;
    cin.get(c);
    if(c=='\n')return 0;
    main();
    cout<<c;
    return 0;
}

1 Comment

Note that calling main (recursively or otherwise) from a C++ program is illegal. See, for example: Can main function call itself in C++?.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.