14

I want to use recursion to reverse a string in python so it displays the characters backwards (i.e "Hello" will become "olleh"/"o l l e h".

I wrote one that does it iteratively:

def Reverse( s ):
    result = ""
    n = 0
    start = 0
    while ( s[n:] != "" ):
        while ( s[n:] != "" and s[n] != ' ' ):
            n = n + 1
            result = s[ start: n ] + " " + result
            start = n
    return result

But how exactly do I do this recursively? I am confused on this part, especially because I don't work with python and recursion much.

Any help would be appreciated.

martineau
  • 119,623
  • 25
  • 170
  • 301
Eric
  • 1,191
  • 5
  • 14
  • 17

8 Answers8

36
def rreverse(s):
    if s == "":
        return s
    else:
        return rreverse(s[1:]) + s[0]

(Very few people do heavy recursive processing in Python, the language wasn't designed for it.)

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • Ok that works but how exactly does the bottom part work? You are calling the function rreverse on the 1st element of string and printing out the 0th element out. How exactly does the rreverse(s[1:]) get incremented each time? – Eric Apr 03 '11 at 22:26
  • @Eric recursive call is made on the substring of s starting from the second element (e.g S[1:] gives you s without the first element). He is then appending the result of the recursive call to the first character of s, e.g. s[0]. – Asterisk Apr 03 '11 at 22:29
  • What's the complexity – sarath joseph Apr 27 '15 at 06:59
  • Complexity is O(n) – uday1889 Nov 11 '17 at 13:25
34

To solve a problem recursively, find a trivial case that is easy to solve, and figure out how to get to that trivial case by breaking the problem down into simpler and simpler versions of itself.

What is the first thing you do in reversing a string? Literally the first thing? You get the last character of the string, right?

So the reverse of a string is the last character, followed by the reverse of everything but the last character, which is where the recursion comes in. The last character of a string can be written as x[-1] while everything but the last character is x[:-1].

Now, how do you "bottom out"? That is, what is the trivial case you can solve without recursion? One answer is the one-character string, which is the same forward and reversed. So if you get a one-character string, you are done.

But the empty string is even more trivial, and someone might actually pass that in to your function, so we should probably use that instead. A one-character string can, after all, also be broken down into the last character and everything but the last character; it's just that everything but the last character is the empty string. So if we handle the empty string by just returning it, we're set.

Put it all together and you get:

def backward(text):
    if text == "":
        return text
    else:
        return text[-1] + backward(text[:-1])

Or in one line:

backward = lambda t: t[-1] + backward(t[:-1]) if t else t

As others have pointed out, this is not the way you would usually do this in Python. An iterative solution is going to be faster, and using slicing to do it is going to be faster still.

Additionally, Python imposes a limit on stack size, and there's no tail call optimization, so a recursive solution would be limited to reversing strings of only about a thousand characters. You can increase Python's stack size, but there would still be a fixed limit, while other solutions can always handle a string of any length.

kindall
  • 178,883
  • 35
  • 278
  • 309
9

I just want to add some explanations based on Fred Foo's answer. Let's say we have a string called 'abc', and we want to return its reverse which should be 'cba'.

def reverse(s):
    if s == "":
        return s
    else:
        return reverse(s[1:]) + s[0]
   
             
s = "abc"
print (reverse(s)) 

How this code works is that: when we call the function

reverse('abc')                       #s = abc
=reverse('bc') + 'a'                 #s[1:] = bc    s[0] = a
=reverse('c') + 'b' + 'a'            #s[1:] = c     s[0] = a
=reverse('') + 'c' + 'b' + 'a'
='cba'
cigien
  • 57,834
  • 11
  • 73
  • 112
Kailey
  • 191
  • 2
  • 5
2

If this isn't just a homework question and you're actually trying to reverse a string for some greater goal, just do s[::-1].

bradley.ayers
  • 37,165
  • 14
  • 93
  • 99
1
def reverse_string(s):
    if s: return s[-1] + reverse_string(s[0:-1])
    else: return s

or

def reverse_string(s):
    return s[-1] + reverse_string(s[0:-1]) if s else s
Jarek Przygódzki
  • 4,284
  • 2
  • 31
  • 41
1

I know it's too late to answer original question and there are multiple better ways which are answered here already. My answer is for documentation purpose in case someone is trying to implement tail recursion for string reversal.

def tail_rev(in_string,rev_string):
    if in_string=='':
        return rev_string
    else:
        rev_string+=in_string[-1]
        return tail_rev(in_string[:-1],rev_string)
    
in_string=input("Enter String: ")
rev_string=tail_rev(in_string,'')
print(f"Reverse of {in_string} is {rev_string}") 
cigien
  • 57,834
  • 11
  • 73
  • 112
Ashish S
  • 141
  • 1
  • 7
0
s = input("Enter your string: ")

def rev(s):
    if len(s) == 1:
        print(s[0])
        exit()
    else:
        #print the last char in string
        #end="" prints all chars in string on same line
        print(s[-1], end="")
        """Next line replaces whole string with same
         string, but with 1 char less"""
        return rev(s.replace(s, s[:-1]))

rev(s)
Troy
  • 101
  • 9
0

if you do not want to return response than you can use this solution. This question is part of LeetCode.

class Solution:
    i = 0
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        if self.i >= (len(s)//2):
            return
        s[self.i], s[len(s)-self.i-1] = s[len(s)-self.i-1], s[self.i]
        self.i += 1
        self.reverseString(s)
bhargav3vedi
  • 521
  • 1
  • 6
  • 11