gpt4 book ai didi

python - 我可以在 Python 2.7 中编写一个执行符号计算的函数吗?

转载 作者:太空狗 更新时间:2023-10-29 21:04:07 25 4
gpt4 key购买 nike

我目前正在从 Java 过渡到 Python,并开始尝试创建一个计算器,该计算器可以对中缀符号的数学表达式执行符号运算(不使用 Sympy 等自定义模块 ).目前,它被构建为接受以空格分隔的字符串,并且只能执行 (、)、+、-、* 和/运算符。不幸的是,我想不出简化符号表达式的基本算法。

例如,给定字符串 '2 * ( ( 9/6 ) + 6 * x )',我的程序应执行以下步骤:

  1. 2 * ( 1.5 + 6 * x )
  2. 3 + 12 * x

但是我无法让程序在分发 2 时忽略 x。 此外,我如何处理 'x * 6/x' 以便它在简化后返回 '6'?

编辑:为了澄清,我所说的“符号”是指在执行剩余计算时,它会在输出中留下像“A”和“f”这样的字母。

编辑 2:我(大部分)完成了代码。如果将来有人偶然发现这篇文章,或者如果你们中的任何人感到好奇,我会把它张贴在这里。

    def reduceExpr(useArray):

# Use Python's native eval() to compute if no letters are detected.
if (not hasLetters(useArray)):
return [calculate(useArray)] # Different from eval() because it returns string version of result

# Base case. Returns useArray if the list size is 1 (i.e., it contains one string).
if (len(useArray) == 1):
return useArray

# Base case. Returns the space-joined elements of useArray as a list with one string.
if (len(useArray) == 3):
return [' '.join(useArray)]

# Checks to see if parentheses are present in the expression & sets.
# Counts number of parentheses & keeps track of first ( found.
parentheses = 0
leftIdx = -1

# This try/except block is essentially an if/else block. Since useArray.index('(') triggers a KeyError
# if it can't find '(' in useArray, the next line is not carried out, and parentheses is not incremented.
try:
leftIdx = useArray.index('(')
parentheses += 1
except Exception:
pass

# If a KeyError was returned, leftIdx = -1 and rightIdx = parentheses = 0.
rightIdx = leftIdx + 1

while (parentheses > 0):
if (useArray[rightIdx] == '('):
parentheses += 1
elif (useArray[rightIdx] == ')'):
parentheses -= 1
rightIdx += 1

# Provided parentheses pair isn't empty, runs contents through again; else, removes the parentheses
if (leftIdx > -1 and rightIdx - leftIdx > 2):
return reduceExpr(useArray[:leftIdx] + [' '.join(['(',reduceExpr(useArray[leftIdx+1:rightIdx-1])[0],')'])] + useArray[rightIdx:])
elif (leftIdx > -1):
return reduceExpr(useArray[:leftIdx] + useArray[rightIdx:])

# If operator is + or -, hold the first two elements and process the rest of the list first
if isAddSub(useArray[1]):
return reduceExpr(useArray[:2] + reduceExpr(useArray[2:]))
# Else, if operator is * or /, process the first 3 elements first, then the rest of the list
elif isMultDiv(useArray[1]):
return reduceExpr(reduceExpr(useArray[:3]) + useArray[3:])
# Just placed this so the compiler wouldn't complain that the function had no return (since this was called by yet another function).
return None

最佳答案

在对符号进行操作之前,您需要进行更多处理。您想要获得的形式是一棵操作树,其值在叶节点中。首先,您需要在字符串上运行词法分析器以获取元素——尽管如果您总是有以空格分隔的元素,那么只拆分字符串可能就足够了。然后您需要使用您需要的一些语法来解析该标记数组。

如果您需要有关语法和解析文本的理论信息,请从这里开始:http://en.wikipedia.org/wiki/Parsing如果您需要更实用的东西,请转到 https://github.com/pyparsing/pyparsing (你不必使用 pyparsing 模块本身,但他们的文档有很多有趣的信息)或 http://www.nltk.org/book

2 * ( ( 9/6 ) + 6 * x ),你需要像这样到达一棵树:

      *
2 +
/ *
9 6 6 x

然后您可以访问每个节点并决定是否要简化它。常量运算将是最容易消除的运算 - 只需计算结果并将“/”节点替换为 1.5,因为所有子节点都是常量。

有很多策略可以继续,但本质上你需要找到一种方法来遍历树并修改它,直到没有任何东西可以改变。

如果你想打印结果,只需再次遍历树并产生一个描述它的表达式。

关于python - 我可以在 Python 2.7 中编写一个执行符号计算的函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6699338/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com