我想反转堆栈,但我不知道如何使用递归来反转这个......如何在不使用递归的情况下反转堆栈

时间:2021-01-01 15:26:11

标签: python class oop recursion stack

我想通过使用堆栈数据结构而不使用递归来反转字符串

<块引用>

str= 我们击败了 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) 

为什么我不能使用下面的代码来反转...

def rev(self):
    self.container.reverse()

2 个答案:

答案 0 :(得分:0)

就地修改与返回修改后的副本

假设您有一个名为“CookieJar”的容器类

CookieJar 有一个名为 insert()

的方法

假设我们执行以下代码:

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

问题:

  • cj 是否与调用 insert() 方法之前相同?
  • output 中究竟存储了什么?

在计算机编程中,有两种方法可以修改 cookie jar 的内容:

<头>
范式的正式名称 改变输入 输出
[未知名称] 保留输入的 cookie jar。 输出cookie jar的修改副本
就地修改 修改原来的cookie jar 在python中,输出None。在 Python 以外的语言(Java、C# 等)中,这将被称为“void 返回方法

计算机程序员最常犯的错误之一是他们认为修改器会返回容器的修改副本。

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 

reverse() 类的 deque 方法就地修改 deques
reverse() 输出 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))
<头>
就地修改 返回修改后的副本
执行rstrip()后,txt会发生什么? txt 变成:" kiwi" txt 还是原来的" kiwi "
rstrip() 返回的值是多少? 返回值为None 返回值为" kiwi"

计算机程序员在选择使用哪种范式方面不一致。

来自 deque 库的 collections 类的 mutator 方法就地修改了 deque

字符串类 str 的 python mutator 方法,永远不要修改原始字符串。

答案 1 :(得分:0)

普通列表和普通函数

如果您只需要实现一个堆栈,我认为没有理由使用 collections.deque。我们可以轻松地围绕一个简单的列表进行构建,[] -

# 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)

使用堆栈很直观 -

# 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

让它感觉更像蟒蛇

如果你想让stack更有面向对象的感觉,我们可以围绕普通函数添加一个接口-

# 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)

现在我们可以这样写main -

# 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

扩展堆栈模块

继续向 Stack 模块添加其他功能 -

# stack.py (continued)

def reverse(t):
  t.reverse()

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

将您的新功能包装在面向对象的界面中 -

# 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)        # <-

让我们验证 seekreverse 工作 -

# 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

相关阅读

recent Q&A 中,我展示了如何设计类似于上面 stack 的模块。如果您想了解随着程序的发展如何应用这种技术,我鼓励您查看该帖子 :D


持久堆栈

作为一个有趣的练习,我们可以在不使用 dequelist 或任何其他内置数据容器的情况下实现堆栈。相反,我们将使用普通的 None 和匿名函数。我分享这个例子是为了让你意识到程序员可以在他们的想象中构建任何东西,即使你使用的语言不包含特定的功能 -

# 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)

不是使用 .append.pop.reverse 修改底层堆栈,而是每个堆栈操作都会创建一个堆栈。请注意我们如何unload 堆栈两次(或更多),如果我们愿意 -

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