鱼C论坛

 找回密码
 立即注册
12
返回列表 发新帖
楼主: urbanlife

python语言的二叉树计算

[复制链接]
发表于 2023-12-30 17:38:15 | 显示全部楼层
urbanlife 发表于 2023-12-30 17:37
Traceback (most recent call last):
  File "E:\One ...


根据您提供的错误信息,出现了一个`AttributeError: 'list' object has no attribute 'lchild'`的错误,意味着在代码的某处尝试访问了列表对象的`lchild`属性,但是列表对象没有此属性。根据这个错误,我检查了代码,并发现了问题所在。

问题在于在`buildExpressionTree`函数中,没有正确地处理运算符栈(`optr_stack`)和表达式树栈(`expt_stack`)的定义和初始化。这导致在返回`expt_stack`时,实际上返回了一个包含单个元素的列表,而不是预期的表达式树根节点。

为了解决这个问题,请按照下面的修正代码进行修改:

  1. def buildExpressionTree(expression, variables):
  2.     operators = {'+', '-', '*', '/'}  # 运算符的集合
  3.     optr_stack = []  # 运算符栈
  4.     expt_stack = []  # 表达式树栈

  5.     for char in expression:
  6.         if char == ' ':  # 忽略空格
  7.             continue
  8.         elif char == '(':
  9.             optr_stack.append(char)
  10.         elif char.isalpha():
  11.             node = TreeNode(variables[char])  # 使用变量对应的值来创建操作数结点
  12.             expt_stack.append(node)
  13.         elif char in operators:
  14.             while optr_stack and optr_stack[-1] != '(' and precedence(optr_stack[-1]) >= precedence(char):
  15.                 root = TreeNode(optr_stack.pop())
  16.                 root.rchild = expt_stack.pop()
  17.                 root.lchild = expt_stack.pop()
  18.                 expt_stack.append(root)

  19.             optr_stack.append(char)
  20.         elif char == ')':
  21.             while optr_stack and optr_stack[-1] != '(':
  22.                 root = TreeNode(optr_stack.pop())
  23.                 root.rchild = expt_stack.pop()
  24.                 root.lchild = expt_stack.pop()
  25.                 expt_stack.append(root)

  26.             if optr_stack and optr_stack[-1] == '(':
  27.                 optr_stack.pop()

  28.     while optr_stack:
  29.         root = TreeNode(optr_stack.pop())
  30.         root.rchild = expt_stack.pop()
  31.         root.lchild = expt_stack.pop()
  32.         expt_stack.append(root)

  33.     return expt_stack[0]

  34. expression = "a*(b-c)+d*(e+f)"
  35. variables = {'a': 2, 'b': 3, 'c': 4, 'd': 5, 'e': 6, 'f': 7}
  36. root = buildExpressionTree(expression, variables)
  37. result = evaluateExpressionTree(root)
  38. print("表达式的值为:", result)
复制代码


这样修改后,重新运行代码应该可以正确计算表达式的值了。希望这次能帮助到您。如有任何问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-30 17:44:01 | 显示全部楼层
FishC 发表于 2023-12-30 17:33
当然,请看下面的代码,我为每一行添加了注释以解释其作用:


FishC 发表于 2023-12-30 17:33
当然,请看下面的代码,我为每一行添加了注释以解释其作用:

Traceback (most recent call last):
  File "E:\OneDrive - Ormesby Primary\python\大作业\二叉树计算.py", line 83, in <module>
    result = evaluateExpressionTree(root)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\OneDrive - Ormesby Primary\python\大作业\二叉树计算.py", line 10, in evaluateExpressionTree
    if root.lchild is None and root.rchild is None:
       ^^^^^^^^^^^
AttributeError: 'list' object has no attribute 'lchild
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-30 17:45:25 | 显示全部楼层
urbanlife 发表于 2023-12-30 17:44
FishC 发表于 2023-12-30 17:33
当然,请看下面的代 ...


非常抱歉,我在之前的代码中犯了一个错误。从错误信息来看,似乎是因为传递给`evaluateExpressionTree()`函数的`root`参数不是期望的`TreeNode`对象,而是一个列表对象。

这可能是由于`buildExpressionTree()`函数在构建表达式树时返回了一个栈(列表),而不是返回根节点。

为了解决这个问题,我会对`buildExpressionTree()`函数进行修改,以确保它返回正确的根节点。

请使用以下修改后的代码:

  1. class TreeNode:
  2.     def __init__(self, data):
  3.         self.data = data  # 结点的数据(可以是操作数或运算符)
  4.         self.lchild = None  # 左子结点
  5.         self.rchild = None  # 右子结点

  6. def evaluateExpressionTree(root):
  7.     # 如果根节点为操作数,则返回该操作数的值
  8.     if root.lchild is None and root.rchild is None:
  9.         return int(root.data)
  10.     else:
  11.         # 递归计算左右子树的值
  12.         left_val = evaluateExpressionTree(root.lchild)
  13.         right_val = evaluateExpressionTree(root.rchild)
  14.         
  15.         # 根据根节点的运算符进行相应的计算
  16.         if root.data == '+':
  17.             return left_val + right_val
  18.         elif root.data == '-':
  19.             return left_val - right_val
  20.         elif root.data == '*':
  21.             return left_val * right_val
  22.         elif root.data == '/':
  23.             return left_val / right_val

  24. def buildExpressionTree(expression):
  25.     operators = set()  # 运算符的集合
  26.     optr_stack = []   # 运算符栈
  27.     expt_stack = []   # 表达式树栈

  28.     # ... 在这里添加代码来构建表达式树 ...

  29.     return expt_stack[0]  # 返回根节点

  30. def precedence(op):
  31.     # 定义运算符的优先级,数字越大优先级越高
  32.     if op == '+' or op == '-':
  33.         return 1
  34.     elif op == '*' or op == '/':
  35.         return 2
  36.     else:
  37.         return 0

  38. expression = "a*(b-c)+d*(e+f)"
  39. root = buildExpressionTree(expression)
  40. result = evaluateExpressionTree(root)
  41. print("表达式的值为:", result)
复制代码


希望这次的修改能够解决问题。如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-30 17:54:57 | 显示全部楼层
FishC 发表于 2023-12-30 17:33
当然,请看下面的代码,我为每一行添加了注释以解释其作用:

class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None

def evaluateExpressionTree(root):
    if root.left is None and root.right is None:
        return int(root.val)
    else:
        left_val = evaluateExpressionTree(root.left)
        right_val = evaluateExpressionTree(root.right)
        
        if root.val == '+':
            return left_val + right_val
        elif root.val == '-':
            return left_val - right_val
        elif root.val == '*':
            return left_val * right_val
        elif root.val == '/':
            return left_val / right_val

def buildExpressionTree(expression, variables):
    operators = set(['+', '-', '*', '/'])
    optr_stack = []
    expt_stack = []
   
    for char in expression:
        if char == ' ':
            continue
        elif char == '(':
            optr_stack.append(char)
        elif char.isalpha():
            node = TreeNode(variables[char])
            expt_stack.append(node)
        elif char in operators:
            while (
                optr_stack
                and optr_stack[-1] != '('
                and precedence(optr_stack[-1]) >= precedence(char)
            ):
                root = TreeNode(optr_stack.pop())
                root.right = expt_stack.pop()
                root.left = expt_stack.pop()
                expt_stack.append(root)
            
            optr_stack.append(char)
        elif char == ')':
            while optr_stack and optr_stack[-1] != '(':
                root = TreeNode(optr_stack.pop())
                root.right = expt_stack.pop()
                root.left = expt_stack.pop()
                expt_stack.append(root)
            
            if optr_stack and optr_stack[-1] == '(':
                optr_stack.pop()
   
    while optr_stack:
        root = TreeNode(optr_stack.pop())
        root.right = expt_stack.pop()
        root.left = expt_stack.pop()
        expt_stack.append(root)
   
    return expt_stack[0]

def precedence(op):
    if op == '+' or op == '-':
        return 1
    elif op == '*' or op == '/':
        return 2
    else:
        return 0

expression = "a*(b-c)+d*(e+f)"
variables = {'a': 2, 'b': 3, 'c': 4, 'd': 5, 'e': 6, 'f': 7}

root = buildExpressionTree(expression, variables)
result = evaluateExpressionTree(root)
print("表达式的值为:", result)
给每行代码加上注释
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-30 17:55:24 | 显示全部楼层
urbanlife 发表于 2023-12-30 17:54
class TreeNode:
    def __init__(self, val):
    ...


当然,请看下面的代码,我为每一行添加了注释以解释其作用:

  1. class TreeNode:
  2.     def __init__(self, val):
  3.         self.val = val  # 结点的值(可以是操作数或运算符)
  4.         self.left = None  # 左子结点
  5.         self.right = None  # 右子结点

  6. def evaluateExpressionTree(root):
  7.     # 递归计算表达式树的值
  8.     if root.left is None and root.right is None:
  9.         return int(root.val)  # 如果是叶子结点(操作数),返回其值
  10.     else:
  11.         # 递归计算左右子树的值
  12.         left_val = evaluateExpressionTree(root.left)
  13.         right_val = evaluateExpressionTree(root.right)

  14.         # 根据根节点的运算符进行相应的计算
  15.         if root.val == '+':
  16.             return left_val + right_val
  17.         elif root.val == '-':
  18.             return left_val - right_val
  19.         elif root.val == '*':
  20.             return left_val * right_val
  21.         elif root.val == '/':
  22.             return left_val / right_val

  23. def buildExpressionTree(expression, variables):
  24.     operators = set()  # 运算符的集合
  25.     optr_stack = []  # 运算符栈
  26.     expt_stack = []  # 表达式树栈

  27.     for char in expression:
  28.         if char == ' ':  # 忽略空格
  29.             continue
  30.         elif char == '(':  # 遇到左括号时将其压入运算符栈
  31.             optr_stack.append(char)
  32.         elif char.isalpha():  # 遇到字母时创建一个操作数结点,并将其压入表达式树栈
  33.             node = TreeNode(variables[char])
  34.             expt_stack.append(node)
  35.         elif char in operators:  # 遇到运算符时
  36.             while (optr_stack and optr_stack[-1] != '('
  37.                    and precedence(optr_stack[-1]) >= precedence(char)):
  38.                 # 比较运算符的优先级,如果栈顶的运算符的优先级大于等于当前运算符,
  39.                 # 则弹出栈顶的运算符,创建相应的表达式树结点,并将其加入表达式树栈
  40.                 root = TreeNode(optr_stack.pop())
  41.                 root.right = expt_stack.pop()
  42.                 root.left = expt_stack.pop()
  43.                 expt_stack.append(root)

  44.             optr_stack.append(char)  # 将当前运算符压入运算符栈
  45.         elif char == ')':  # 遇到右括号时
  46.             while optr_stack and optr_stack[-1] != '(':
  47.                 # 弹出栈顶的运算符,创建相应的表达式树结点,并将其加入表达式树栈
  48.                 root = TreeNode(optr_stack.pop())
  49.                 root.right = expt_stack.pop()
  50.                 root.left = expt_stack.pop()
  51.                 expt_stack.append(root)

  52.             if optr_stack and optr_stack[-1] == '(':  # 弹出左括号
  53.                 optr_stack.pop()

  54.     while optr_stack:
  55.         # 当表达式扫描完毕后,如果还有运算符在运算符栈中,则将其弹出,
  56.         # 创建相应的表达式树结点,并将其加入表达式树栈
  57.         root = TreeNode(optr_stack.pop())
  58.         root.right = expt_stack.pop()
  59.         root.left = expt_stack.pop()
  60.         expt_stack.append(root)

  61.     return expt_stack

  62. def precedence(op):
  63.     # 定义运算符的优先级,数字越大优先级越高
  64.     if op == '+' or op == '-':
  65.         return 1
  66.     elif op == '*' or op == '/':
  67.         return 2
  68.     else:
  69.         return 0

  70. expression = "a*(b-c)+d*(e+f)"
  71. variables = {'a': 2, 'b': 3, 'c': 4, 'd': 5, 'e': 6, 'f': 7}

  72. root = buildExpressionTree(expression, variables)
  73. result = evaluateExpressionTree(root)
  74. print("表达式的值为:", result)
复制代码


希望这样的注释可以帮助你更好地理解代码的功能。如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-24 01:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表