I want to reverse the stack but i dont know how to use recursion for reversing this... How can i reverse the stack without using Recursion
Asked Answered
K

2

0

I want to reverse a string by using Stack Data Structure without using recursion

str= we defeated Corona

reversed str = anoroC detaefed ew

from collections import deque

class Stack:
    def __init__(self):
        self.container = deque()
    def rev(self):
        nstk= deque()
        for i in self.container(len(self.container),0,-1):
            nstk.append(i)
        return nstk
    def push(self,val):
        self.container.append(val)
    def peek(self):
        return self.container
        
st = Stack()
lst= list('we defeated Corona')
st.push(lst)
print(st.peek())
revStack= st.rev()
print(revStack) 

Why i Cant use this below code to reverse...

def rev(self):
    self.container.reverse()
Kiel answered 1/1, 2021 at 15:26 Comment(3)
the reversed string is just str[::-1] which provides your desired output.Dillydally
Can you please help me by just Sharing some code for this.. I am beginnerKiel
@Sauravsharma--I'm not clear of your exact problem. Are you trying to create a wrapper for dequeue that does operations including reverse? Note that deque itself has a reverse operation. Note also your self.container.append(val) is append a list rather than elements of the list.Dillydally
B
0

Modifying In-Place versus Returning a Modified Copy

Suppose you have a container class named "CookieJar"

CookieJar has a method named insert()

Suppose we execute the following code:

cj = CookieJar()
# [some time later...]
output = cj.insert("new cookie")

QUESTIONS:

  • Is cj the same as it was before the insert() method was called?
  • What exactly is stored in output?

In computer programming there are two ways to modify the contents of a cookie jar:

official name of the paradigm changes to input output
[unknown name] leave the input cookie jar alone. output a modified copy of the cookie jar
MODIFY IN-PLACE Modify the original cookie jar In python, output None. In languages other than python, (Java, C#, etc...) this would be known as a "void returning method"

One of the most common mistakes computer programmers make is that they assume that a mutator will return a modified copy of the container.

from collections import deque

my_deque = deque()
my_deque.appendleft("a")
my_deque.appendleft("b")
my_deque.appendleft("c")

print(my_deque)

output = my_deque.reverse()
print(output)
# output == None 

The reverse() method of the deque class modifies deques in-place.
reverse() outputs None

txt = "  kiwi  "

print("BEFORE `rstrip` txt is: ", repr(txt))

# ABOUT RSTRIP():
#     RSTRIP()` removes `\n`, `\r` `\t`, space, etc...
#     from the right-hand side of the string

output = txt.rstrip()

print("output is:", repr(output))
print("AFTER EXECUTING `rstrip()`, txt is: ", repr(txt))
MODIFY IN-PLACE RETURN MODIFIED COPY
AFTER EXECUTING rstrip(), what happens to txt? txt becomes: " kiwi" txt is still the original " kiwi "
What is the value returned by rstrip()? return value isNone return value is " kiwi"

Computer programmers are inconsistent about which paradigm they choose to work with.

mutator methods of the deque class from the collections library modify the dequein-place.

python mutator methods for the string-class str, never modify the original string.

Bolick answered 1/1, 2021 at 16:8 Comment(0)
C
0

plain list and ordinary functions

I see no reason to reach for collections.deque if you only need to implement a stack. We can easily build around a plain list, [] -

# stack.py

def empty():
  return []

def push(t, x):
  t.append(x)

def pop(t):
  return t.pop()

def load(t, iterable):
  for x in iterable:
    push(t, x)

def unload(t):
  while t:
    yield pop(t)

Using the stack is intuitive -

# main.py

import stack

input = "we have not defeated corona"

s = stack.empty()
stack.load(s, input)

output = "".join(stack.unload(s))

print(output)
anoroc detaefed ton evah ew

make it feel more like python

If you want stack to have a more object-oriented feel, we can add an interface around the plain functions -

# stack.py (continued)

class stack:
  def empty(): return stack(empty())
  def __init__(self, t): self.t = t
  def push(self, v): return push(self.t, v)
  def pop(self): return pop(self.t)
  def load(self, iterable): return load(self.t, iterable)
  def unload(self): return unload(self.t)

Now we can write main as follows -

# main.py

from stack import stack

input = "we have not defeated corona"

s = stack.empty()
s.load(input)
output = "".join(s.unload())

print(output)
anoroc detaefed ton evah ew

expand the stack module

Go ahead and add other capabilities to the Stack module -

# stack.py (continued)

def reverse(t):
  t.reverse()

def peek(t):
  if not t:
    return None
  else:
    return t[-1]

Wrap your new functions in the object-oriented interface -

# stack.py (continued)

class stack:
  def empty(): ...
  def __init__(): ...
  def push(): ...
  def pop(): ...
  def load(): ...
  def unload(): ...
  def reverse(self): return reverse(self.t)  # <-
  def peek(self): return peek(self.t)        # <-

Let's verify seek and reverse working -

# main.py

from stack import stack

input = "we have not defeated corona"

s = stack.empty()
s.load(input)

print(s.peek())
s.pop()
print(s.peek())
s.reverse()
print(s.peek())
a
n
w

related reading

In a recent Q&A I showed how to design modules similar to stack above. If you want to see how this technique is applied as your program grows, I encourage you to check out that post :D


persistent stack

As a fun exercise, we can implement a stack without using deque, a list, or any other built-in data container. Instead, we'll use plain None and anonymous functions. I share this example so you can realize that the programmer can build anything in their imagination, even if the language you are using doesn't include particular features -

# stack.py

empty = None

def push(t, v):
  return lambda k: k(t, v)

def pop(t):
  if not t:
    raise RuntimeError("cannot pop empty stack")
  else:
    return t(lambda next, v: (next, v))

def load(t, iterable):
  for v in iterable:
    t = push(t, v)
  return t

def unload(t):
  while t:
    (next, v) = pop(t)
    yield v
    t = next

def reverse(t):
  return load(empty, unload(t))

def peek(t):
  if not t:
    return None
  else:
    (_, v) = pop(t)
    return v

class stack:
  def empty(): return stack(empty)
  def __init__(self, t): self.t = t
  def push(self, v): return push(self.t, v)
  def pop(self):
    (next, v) = pop(self.t)
    return (stack(next), v)
  def load(self, iterable): return stack(load(self.t, iterable))
  def unload(self): return unload(self.t)
  def reverse(self): return stack(reverse(self.t))
  def peek(self): return peek(self.t)

Instead of modifying the underlying stack using .append, .pop, or .reverse, each stack operation creates a new stack. Notice how we can unload the stack twice (or more), if we wanted -

from stack import stack

input = "we have not defeated corona"

s = stack.empty().load(input)

print("".join(s.unload()))
print("".join(s.reverse().unload()))
print("".join(s.unload()))
anoroc detaefed ton evah ew
we have not defeated corona
anoroc detaefed ton evah ew
Crackerbarrel answered 1/1, 2021 at 18:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.