题解 | #S-expression#

S-expression

https://www.nowcoder.com/practice/7e6d2dd2e8774db3877f1fce2dd73834

使用 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 表达式运行结束后将弹出。

全部评论

相关推荐

2024-12-29 11:08
湖南工业大学 Java
程序员牛肉:简历没什么大问题了。 而且不要再换项目了。三月份就开暑期实习了,现在都一月份了。实在来不及重新开一下项目了。把一个项目写完或许很快,但是把一个项目搞懂吃透并不简单。所以不要换项目了,把你简历上面的两个项目好好挖一挖吧。 具体 体现在:你能不能流利的说出你的项目的每一个功能点代码实现?你能不能说出在这块除了A技术之外,还有其他技术能够实现嘛?如果有其他技术能够实现,那你这块为什么选择了你当前用的这个技术?
投递牛客等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务