【2025刷题笔记】- 仿LISP运算

刷题笔记合集🔗

仿LISP运算

问题描述

小基 设计了一种简化版的 LISP 语言,其唯一的语法就是括号要配对。

形如 (OP P1 P2 …),括号内元素由单个空格分割。

其中第一个元素 OP 为操作符,后续元素均为其参数,参数个数取决于操作符类型。

注意:

参数 P1, P2 也有可能是另外一个嵌套的 (OP P1 P2 …),当前 OP 类型为 add / sub / mul / div(全小写),分别代表整数的加减乘除法,简单起见,所有 OP 参数个数均为 2。

举例:

  • 输入:(mul 3 -7) 输出:-21
  • 输入:(add 1 2) 输出:3
  • 输入:(sub (mul 2 4) (div 9 3)) 输出:5
  • 输入:(div 1 0) 输出:error

题目涉及数字均为整数,可能为负;

不考虑 32 位溢出翻转,计算过程中也不会发生 32 位溢出翻转,

除零错误时,输出 "error",

除法遇除不尽,向下取整,即 3/2 = 1

输入格式

输入为长度不超过 的字符串,用例保证了无语法错误。

输出格式

输出计算结果或者 "error"。

样例输入

(div 12 (sub 45 45))
(add 1 (div -7 3))

样例输出

error
-2
样例 解释说明
样例1 45减45得0,12除以0为除零错误,输出error
样例2 -7除以3向下取整得-3,1加-3得-2

数据范围

  • 输入字符串长度不超过
  • 保证输入无语法错误

题解

这道题目考察的是表达式解析,需要实现一个简单的LISP解释器。LISP语言的特点是所有表达式都用括号包围,形式统一,便于递归处理。

解题的关键在于如何处理嵌套的表达式。在LISP中,最内层的括号会最先被计算,然后逐层向外。比如(sub (mul 2 4) (div 9 3)),需要先计算(mul 2 4)得到8,再计算(div 9 3)得到3,最后计算(sub 8 3)得到5。

实现上,可以使用栈来辅助解析。基本思路如下:

  1. 从左到右扫描输入字符串
  2. 遇到字符就放入栈中
  3. 当遇到右括号')'时,向前查找对应的左括号'('
  4. 取出左右括号之间的内容,进行解析和计算
  5. 将计算结果转为字符串放回栈中
  6. 重复上述过程,直到处理完整个字符串

具体实现中,要特别注意以下几点:

  • 除零错误的处理:当除数为0时,立即返回"error"
  • 除法的向下取整:对于负数除法,需要特别注意向下取整的实现
  • 参数解析:需要正确分割操作符和参数

这种方法的时间复杂度是O(n),其中n是输入字符串的长度。在最坏情况下,我们需要遍历字符串中的每个字符一次。空间复杂度也是O(n),主要是栈所需的空间。

虽然题目保证输入没有语法错误,但实际编程时还是要注意边界条件和异常情况的处理,使代码更健壮。

参考代码

  • Python
import sys
input = lambda:sys.stdin.readline().strip()
import math

def calculate_lisp(expr):
    stack = []  # 用于存储解析过程中的字符
    left_idx = []  # 记录左括号的位置
    
    for i in range(len(expr)):
        char = expr[i]
        
        if char == ')':
            # 找到对应的左括号
            left_pos = left_idx.pop()
            # 提取括号内的内容
            fragment = stack[left_pos + 1:]
            # 从栈中移除括号内容和左括号
            del stack[left_pos:]
            
            # 解析操作和参数
            parts = ''.join(fragment).split()
            op = parts[0]
            p1 = int(parts[1])
            p2 = int(parts[2])
            
            # 执行操作
            result = perform_operation(op, p1, p2)
            
            # 如果是错误,直接返回
            if result == "error":
                return "error"
            
            # 将结果添加回栈中
            stack.extend(str(result))
        elif char == '(':
            # 记录左括号位置
            left_idx.append(len(stack))
            stack.append(char)
        else:
            # 其他字符直接添加到栈中
            stack.append(char)
    
    # 最终栈中应该只剩下计算结果
    return

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

算法刷题笔记 文章被收录于专栏

本专栏收集并整理了一些刷题笔记

全部评论

相关推荐

牛客78682892...:直接点还好,总比要了简历也不回的强
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务