我正在编写一个程序,用户在其中输入一个后缀表达式并输出答案。Current在for循环中使用"evaluate"函数时,我被卡住了。
Inside my For loop Main.py:
else:
# Debug Code
print('{}: Else'.format(i))
print('{}: Length'.format(len(stack)))
Node.right = stack.pop()
Node.left = stack.pop()
Node = TreeNode(str(i))
stack.push(str(i))
# Debug Code
print('{}: Right Key'.format(Node.right))
print('{}: Left Key'.format(Node.left))
print('{}: Node Key'.format(Node.key))
print('{}: Node Key Type'.format(type(Node.key)))
Node = evaluate(Node)
stack.push(int(Node))
我得到以下错误:
Traceback (most recent call last):
File "c:Usersdpr48main.py", line 49, in <module>
Node = evaluate(Node)
File "c:Usersdpr48main.py", line 10, in evaluate
return evaluate(node.left) + evaluate(node.right)
File "c:Usersdpr48main.py", line 9, in evaluate
if node.key == '+':
AttributeError: 'NoneType' object has no attribute 'key'
所以我的问题是,为什么它不使用"TreeNode"类来获取键值?以及应该将"Node.left"定义为"stack.pop()"值和将"Node.right"定义为为"stack.prop())"值的代码行,它们最终都没有更改,并将它们保留为None,正如我在"调试代码"中发现的那样,我已经实现了该代码来查看程序的内部操作。
提供以下使用的每个类别:
主要.py
from Stack import Stack
from TreeNode import TreeNode
def evaluate(node):
if node.key == '+':
return evaluate(node.left) + evaluate(node.right)
elif node.key == '-':
return evaluate(node.left) - evaluate(node.right)
elif node.key == '*':
return evaluate(node.left) * evaluate(node.right)
elif node.key == '/':
return evaluate(node.left) / evaluate(node.right)
else:
return node.key
stack = Stack()
exp = "23+"
list = [*exp]
for i in list:
if i.isdigit() is True:
# Debug Code
print('{}: True'.format(i))
Node = TreeNode(int(i))
stack.push(int(i))
else:
# Debug Code
print('{}: Else'.format(i))
print('{}: Length'.format(len(stack)))
Node.right = stack.pop()
Node.left = stack.pop()
Node = TreeNode(str(i))
stack.push(str(i))
# Debug Code
print('{}: Right Key'.format(Node.right))
print('{}: Left Key'.format(Node.left))
print('{}: Node Key'.format(Node.key))
print('{}: Node Key Type'.format(type(Node.key)))
Node = evaluate(Node)
stack.push(int(Node))
print(evaluate(stack.node))
堆叠.py
from Node import Node
from LinkedList import LinkedList
class Stack:
def __init__(self):
self.list = LinkedList()
def push(self, new_item):
# Create a new node to hold the item
new_node = Node(new_item)
# Insert the node as the list head (top of stack)
self.list.prepend(new_node)
def pop(self):
# Copy data from list's head node (stack's top node)
popped_item = self.list.head.data
# Remove list head
self.list.remove_after(None)
# Return the popped item
return popped_item
def __len__(self):
node = self.list.head # Start at head of stack to count until stack returns Null
count = 0
while node != None:
node = node.next
count+=1
return count # Returning length of stack
链接列表.py
class LinkedList:
def __init__(self):
self.head = None
self.tail = None
def append(self, new_node):
if self.head == None:
self.head = new_node
self.tail = new_node
else:
self.tail.next = new_node
self.tail = new_node
def prepend(self, new_node):
if self.head == None:
self.head = new_node
self.tail = new_node
else:
new_node.next = self.head
self.head = new_node
def insert_after(self, current_node, new_node):
if self.head == None:
self.head = new_node
self.tail = new_node
elif current_node is self.tail:
self.tail.next = new_node
self.tail = new_node
else:
new_node.next = current_node.next
current_node.next = new_node
def remove_after(self, current_node):
# Special case, remove head
if (current_node == None) and (self.head != None):
succeeding_node = self.head.next
self.head = succeeding_node
if succeeding_node == None: # Remove last item
self.tail = None
elif current_node.next != None:
succeeding_node = current_node.next.next
current_node.next = succeeding_node
if succeeding_node == None: # Remove tail
self.tail = current_node
Node.py
class Node:
def __init__(self, initial_data):
self.data = initial_data
self.next = None
树节点.py
class TreeNode:
# Constructor assigns the given key, with left and right
# children assigned with None.
def __init__(self, key):
self.key = key
self.left = None
self.right = None
有几个问题:
-
Node
是一个类的名称,但您对TreeNode
实例使用相同的名称,从而隐藏类名。这不是主要问题,但肯定不是建议。相关:不要将PascalCase用于实例,而是使用camelCase。所以node
,而不是Node
。 -
当您还没有定义
Node
时,您可以分配给Node.right
,这将在稍后的Node = TreeNode(str(i))
中发生。您应该先分配给Node
(更好的是node
),然后再分配给它的属性。 -
对于
Node.right = stack.pop()
,您显然希望堆栈包含TreeNode
实例,但对于stack.push(str(i))
,您需要字符串。这将导致你描述的问题。堆栈不应填充字符串,而应填充TreeNode
对象。 -
在
else
块的末尾,调用evaluate
,然后将结果值推送到堆栈。这是错误的,应该删除。评估应该只在完成树时进行,而不应该涉及堆栈。堆栈在构建树中起作用,而不是评估树。 -
最后一行
print
访问stack.node
,但stack
没有node
属性。您将希望从堆栈中弹出顶部项,该项(如果输入语法正确)上应该只剩下1个节点,表示树的根。 -
这不是问题,但
i
保证是一个字符串(长度为1),因此不需要对其调用str
。
这是更正后的代码:
for i in list:
if i.isdigit() is True:
node = TreeNode(int(i)) # lowercase name
stack.push(node) # don't push string, but object
else:
node = TreeNode(i) # First create the node
node.right = stack.pop() # Then assign to its attributes
node.left = stack.pop()
stack.push(node) # don't push string
# Don't evaluate here, nor push anything else to the stack
print(evaluate(stack.pop()))