使用 python 比较方便。先将输入的表达式转化为一个嵌套的 list,然后递归地求解每个子表达式的值即可。以下为代码中函数、全局变量的作用
- expr2ls(s):输入一个 S-expression,将其转化为嵌套列表。例如:表达式“( let ( x 4 ) ( if true x y ) )”会转化为 ['let', ['x', 4], ['if', 'true', 'x', 'y']]
- evaluate(e):输入一个表达式(列表/数字/字符串),返回它的值。按照题意处理即可
- variables:字典,记录目前被 let 语句赋值过的变量名
- solve():解决一个测试 testcase
【吐槽一下,发帖有bug,下方代码块没法把我的代码全粘贴进来,无论如何都只有29行。可以自行在排行-Python3 中查看完整代码】
from collections import defaultdict
def expr2ls(s):
t = ""
for atom in s.split():
if atom == '(':
t += '['
elif atom == ')':
t += '],'
elif atom.isdigit():
t += atom + ','
else:
t += f"'{atom}',"
return eval(t[:-1])
variables = defaultdict(list)
def evaluate(e):
if type(e) == list:
if e[0] in "+-*/<>=":
e1, e2 = evaluate(e[1]), evaluate(e[2])
if type(e1) != int or type(e2) != int:
raise TypeError
if e[0] == '/' and e2 == 0:
raise ZeroDivisionError
return (e1+e2, e1-e2, e1*e2, e1//e2, e1<e2, e1>e2, e1==e2)["+-*/<>=".find(e[0])]
elif e[0] == "if":
e1 = evaluate(e[1])
if type(e1) != bool:
raise TypeError
return evaluate(e[2]) if e1 else evaluate(e[3])
elif e[0] == "let":
多说一句,本题中,关于 let 语句的作用域是有歧义的。题干中没有提到,本题的后台数据中也没有出现这种情况,因此不考虑这一点也能AC。
考虑如下的表达式:
( let ( x 1 ) ( + ( let ( x 2 ) x ) x ) )
按理说,内层的 x 值应该为2,外层的 x 值应该为1。因此返回值应该为 3,而不是 4、2或者“Unbound Identifier”。要想实现作用域,需要把字典的值设为一个堆栈。变量赋值时入栈;表达式运行时取栈顶;let 表达式运行结束后将弹出。

京公网安备 11010502036488号