我正在尝试编写一个像@property (nonatomic,weak) id<ProtocolDelegate> protocol_delegate;
这样的数学表达式求解器。
我目前的障碍是弄清楚哪些开启和关闭支架是对应的。
例如,我如何确定worlfram alpha
中哪些括号匹配。该程序将单独解决这些部分中的每一部分,并在这样做时用答案替换原始部分。
因此,举例来说,该程序试图在((1 * 3) / (4 / 2))
中尝试解决的第一部分将是((1 * 3) / (4 / 2))
,因此它会用产品3替换该部分,(1 * 3)
会现在是((1 * 3) / (4 / 2))
。
我目前的代码(如果有用) - http://pastebin.com/Xpayzbff,处理配对的功能是(3 / (4 / 2))
。
谢谢!
答案 0 :(得分:0)
我不会为你编写代码,因为那会破坏这一点,但你可能想要的是Shunting-yard algorithm。它从中缀(人类通常代表一系列操作,操作符在操作数中)转换为后缀(计算机很容易评估,操作符在之后)操作数。)。
以下是在python中为布尔登录执行此操作的人:https://msoulier.wordpress.com/2009/08/01/dijkstras-shunting-yard-algorithm-in-python/
您还可以尝试将语句直接解析为AST,然后您可以对其进行操作。
另外请务必查看tokenizer module for python。
答案 1 :(得分:0)
您可以使用Shunting-Yard算法。但是,涉及算法的完整实现。这是一个更简单,有些天真的版本,可以使您基本了解https://gist.github.com/tiabas/339f5c06f541c176a02c02cc3113d6f7
# Simple Shunting-Yard solution
#
# Given a math expression, parse and evaluate
# the expression
#
# E.g '2+1' => 3, 8/2*4+1 => 17, 2+(1*2) = 4, ((2+4)/2*7) => 21
#
def parse_math_expression(exp):
PRECENDENCE = {
')': 3,
'(': 3,
'*': 1,
'/': 1,
'+': 0,
'-': 0,
}
output = []
operators = []
for ch in exp:
# Handle nested expressions
if ch == ')':
opr = operators.pop(0)
while opr != '(':
output.append(opr)
opr = operators.pop(0)
elif ch.isdigit():
output.append(ch)
else:
# Handle operator prescendence
top_op = None
if len(operators) and operators[0]:
top_op = operators[0]
# Check if top operator has greater prcendencethan current char
if top_op in ['*', '/'] and PRECENDENCE[top_op] > PRECENDENCE[ch]:
output.append(top_op)
operators.pop(0)
# Push operator onto queues
operators.insert(0, ch)
# Handle any leftover operators
while len(operators):
output.append(operators.pop(0))
return output
test1 = "(2+1)"
assert parse_math_expression(test1) == ['2', '1', '+']
test2 = "((2+4)/(2*7))"
assert parse_math_expression(test2) == ['2', '4', '+', '2', '7', '*', '/']
test3 = "(3*2)+(4/2)"
assert parse_math_expression(test3) == ['3', '2', '*','4', '2', '/','+']
def eval_parsed_expression(exp):
OPRS = {
'+': lambda a, b: a + b,
'-': lambda a, b: a - b,
'*': lambda a, b: a * b,
'/': lambda a, b: a / b
}
tmp = []
while len(exp) > 1:
k = exp.pop(0)
while not k in ['*', '-', '+', '/']:
tmp.insert(0, k)
k = exp.pop(0)
o = k
b = tmp.pop(0)
a = tmp.pop(0)
r = OPRS[o](int(a), int(b))
exp.insert(0, r)
return exp[0]
test4 = ['2', '1', '+'] # (2+1*2)
assert eval_parsed_expression(test4) == 3
test5 = ['2', '1', '2', '*', '+'] # (2+1*2)
assert eval_parsed_expression(test5) == 4
test6 = ['3', '2', '*','4', '2', '/','+'] # (3*2)+(4/2)
assert eval_parsed_expression(test6) == 8