在Python中反转堆栈
要反转堆栈,请执行以下操作:在Python中反转堆栈,python,stack,Python,Stack,要反转堆栈,请执行以下操作: 我做了一个空的临时堆栈 我使用了tempstack.push(stack.pop()) 然后将其重命名为stack=tempstack 但它似乎不起作用。知道为什么吗 要调用它,我只想使用reverse(stack),而不是stack=reverse(stack) 看起来您应该编写而不是堆栈。是否为空(): (编辑后)确定,现在不是stack=new\u stack,而是说return new\u stack。应使用stack=reverse(stack)调用该函数
tempstack.push(stack.pop())
stack=tempstack
reverse(stack)
,而不是stack=reverse(stack)
看起来您应该编写
而不是堆栈。是否为空():
(编辑后)确定,现在不是
stack=new\u stack
,而是说return new\u stack
。应使用stack=reverse(stack)
调用该函数
(响应注释)如果返回值不是一个选项,那么我们需要知道有哪些方法可以修改堆栈对象。说出
stack=new\u stack
或stack=stack()
不会在函数之外更改它
像这样的方法应该会奏效:
def reverse(stack):
new_stack = Stack()
while not stack.is_empty():
new_stack.push(stack.pop())
stack._items = new_stack._items
然而,这可能是个坏主意,因为\u items
前面的下划线表明编写堆栈类的人不希望这样使用它
另外,正如@user4815162342所指出的,这可能会使堆栈反转两次,因此我们不应该使用临时的
new\u stack=stack()
而应该使用临时列表。实际上@user4815162342的答案是最好的。看起来您应该编写而不是堆栈。is_empty():
(编辑后)确定,现在不是
stack=new\u stack
,而是说return new\u stack
。应使用stack=reverse(stack)
调用该函数
(响应注释)如果返回值不是一个选项,那么我们需要知道有哪些方法可以修改堆栈对象。说出
stack=new\u stack
或stack=stack()
不会在函数之外更改它
像这样的方法应该会奏效:
def reverse(stack):
new_stack = Stack()
while not stack.is_empty():
new_stack.push(stack.pop())
stack._items = new_stack._items
然而,这可能是个坏主意,因为\u items
前面的下划线表明编写堆栈类的人不希望这样使用它
另外,正如@user4815162342所指出的,这可能会使堆栈反转两次,因此我们不应该使用临时的new\u stack=stack()
而应该使用临时列表。实际上@user4815162342的答案是最好的。添加一个返回值
def reverse(stack):
new_stack = Stack()
while not stack.is_empty():
new_stack.push(stack.pop())
return new_stack
调用函数时,请执行以下操作:
stack = reverse(stack)
您正在为函数内部的堆栈赋值,但不是从调用它的位置。范围问题。添加返回值
def reverse(stack):
new_stack = Stack()
while not stack.is_empty():
new_stack.push(stack.pop())
return new_stack
调用函数时,请执行以下操作:
stack = reverse(stack)
您正在为函数内部的堆栈赋值,但不是从调用它的位置。范围问题。如果您使用实际的
列表
来实现堆栈(即,如果堆栈
继承自列表
或基本上是一个列表),则只需将列表
倒过来:
def reverse_stack(stack):
stack.reverse()
为了避免混淆,我将函数重命名为reverse\u stack
;您仍然可以将其称为reverse
。例如:
>>> stack = [1, 2, 3]
>>> reverse_stack(stack)
>>> stack
[3, 2, 1]
但是,您的堆栈
类似乎不是从列表
继承的,而是将底层的列表
保留在私有属性中,因此您不能在堆栈
上直接使用任何可变序列
API。因此,
版本2,仅使用是空的
,推送
和弹出
方法的堆栈
仅使用Stack
s,而不使用list
s或deque
s等。首先,使用两个助手函数:
def reverse_copy_stack(stack, rev_stack=None):
'''Return a reversed copy of stack, which is emptied.
rev_stack receives the reversed copy if it's not None
'''
if rev_stack is None:
rev_stack = Stack()
while not stack.is_empty():
rev_stack.push(stack.pop())
return rev_stack
def copy_stack(stack):
'''Return a copy of stack, which is emptied.'''
return reverse_copy_stack( reverse_copy_stack(stack))
现在我们可以实现反向堆栈
:
def reverse_stack(stack):
'''Reverse stack in-place'''
new_stack = copy_stack(stack)
# Empty stack
while not stack.is_empty():
stack.pop()
# put reversed copy of new_stack in stack
reverse_copy_stack(new_stack, stack)
如果您正在使用实际的
list
s来实现堆栈(即,如果Stack
继承自list
或基本上是一个列表),则只需将list
倒过来:
def reverse_stack(stack):
stack.reverse()
为了避免混淆,我将函数重命名为reverse\u stack
;您仍然可以将其称为reverse
。例如:
>>> stack = [1, 2, 3]
>>> reverse_stack(stack)
>>> stack
[3, 2, 1]
但是,您的堆栈
类似乎不是从列表
继承的,而是将底层的列表
保留在私有属性中,因此您不能在堆栈
上直接使用任何可变序列
API。因此,
版本2,仅使用是空的
,推送
和弹出
方法的堆栈
仅使用Stack
s,而不使用list
s或deque
s等。首先,使用两个助手函数:
def reverse_copy_stack(stack, rev_stack=None):
'''Return a reversed copy of stack, which is emptied.
rev_stack receives the reversed copy if it's not None
'''
if rev_stack is None:
rev_stack = Stack()
while not stack.is_empty():
rev_stack.push(stack.pop())
return rev_stack
def copy_stack(stack):
'''Return a copy of stack, which is emptied.'''
return reverse_copy_stack( reverse_copy_stack(stack))
现在我们可以实现反向堆栈
:
def reverse_stack(stack):
'''Reverse stack in-place'''
new_stack = copy_stack(stack)
# Empty stack
while not stack.is_empty():
stack.pop()
# put reversed copy of new_stack in stack
reverse_copy_stack(new_stack, stack)
首先复制堆栈,清空原始堆栈,然后按照您的方法操作
def reverse(stack):
old_stack = stack[:]
while not stack.is_empty():
stack.pop()
while not old_stack.is_empty():
stack.push(old_stack.pop())
首先复制堆栈,清空原始堆栈,然后按照您的方法操作
def reverse(stack):
old_stack = stack[:]
while not stack.is_empty():
stack.pop()
while not old_stack.is_empty():
stack.push(old_stack.pop())
正如其他人所指出的,最后一项作业没有任何作用。然而,这里练习背后的想法可能是只使用标准堆栈原语
push
,pop
,是空的
,而不依赖确切的堆栈实现来使用list.reverse
等
需要注意的关键点是,堆栈是后进先出结构,因此读取其内容会自动以相反的顺序生成它们。这就是为什么使用另一个堆栈作为临时存储的解决方案不起作用的原因:
def reverse(stack):
# Doesn't work
temp = Stack()
while not stack.is_empty():
temp.push(stack.pop())
while not temp.is_empty():
stack.push(temp.pop())
在这里,堆栈内容被反转了两次:一次是从原始堆栈中读取,一次是从临时堆栈中读取,因此最终以原始顺序的堆栈内容结束。要实际反转堆栈,您需要将项目提取到列表中,然后按顺序(从开始到结束)遍历它,并在项目到达时将其推到原始堆栈上:
def reverse(stack):
items = []
while not stack.is_empty():
items.append(stack.pop())
for item in items:
stack.push(item)
编辑:受BrianO回答的启发,这里有一个版本根本不使用列表(但实例化了两个临时堆栈):
这里的想法是利用这样一个事实,即复制堆栈确实会反转内容-只是将其复制回会再次反转。所以我们就复制三个