仿LISP运算
2026华为OD机试双机位C卷 - 华为OD上机考试双机位C卷
华为OD机试双机位C卷真题目录点击查看: 【全网首发】2026华为OD机位C卷 机考真题题库含考点说明以及在线OJ(OD上机考试双机位C卷)
题目描述
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
输入描述
输入为长度不超过512的字符串,用例保证了无语法错误
输出描述
输出计算结果或者“error”
示例1
输入
(div 12 (sub 45 45))
输出
error
说明
示例2
输入
(add 1 (div -7 3))
输出
-2
说明
向下取整(floor)结果为:
解题思路
题目分析
题目要求解析并计算一个仿 LISP 语言的表达式。
表达式的格式是 (OP P1 P2),其中 OP 是操作符(add, sub, mul, div),P1 和 P2 是参数,可能是整数,也可能是嵌套的表达式。
我们需要处理嵌套的括号结构,计算出最终结果。
题目还特别提到了一些细节:
- 除法:除不尽时向下取整(例如 , )。
- 错误处理:除以 0 时输出 "error"。
- 整数范围:不会发生 32 位溢出。
解题策略:双栈法
这类嵌套表达式求值问题,经典的解法是使用栈 (Stack)。 我们可以使用两个栈:
- 操作符栈 (
operaStack):用于存储操作符(add, sub, mul, div)。 - 数字栈 (
numStack):用于存储操作数和中间计算结果。
算法流程
遍历输入字符串的每一个字符:
-
遇到左括号
(:- 这意味着一个新的表达式开始了。
- 紧接着左括号的 3 个字符一定是操作符(add, sub, mul, div)。
- 将操作符提取出来,压入
operaStack。 - 跳过操作符,继续处理后续字符。
-
遇到右括号
):- 这意味着一个当前层的表达式结束了。
- 在遇到右括号之前,如果有未处理的数字字符串,先将其解析为整数并压入
numStack。 - 此时,
numStack的栈顶两个元素分别是该表达式的参数 和 (注意栈是后进先出,所以先弹出的是 )。 - 从
operaStack弹出对应的操作符。 - 执行计算:
result = calc(op, P1, P2)。 - 将计算结果
result压回numStack,作为外层表达式的一个参数。
-
遇到空格
:- 空格是分隔符。
- 如果在空格之前有未处理的数字字符串,将其解析为整数并压入
numStack。
-
遇到数字或负号:
- 记录数字字符串的起始位置,直到遇到空格或右括号为止。
关键细节处理
-
除法向下取整:
- 在 C++/Java 中,整数除法
/是向零取整(截断)。 - 例如:
3 / 2 = 1(正确),-4 / 3 = -1(错误,题目要求向下取整,应为 -2)。 - 对于负数除法,如果不能整除,需要额外减 1。
- Python 的
//操作符和math.floor默认就是向下取整,处理起来比较方便。 - JavaScript 的
Math.floor也是向下取整。
- 在 C++/Java 中,整数除法
-
除以零:
- 在执行除法前检查除数是否为 0。如果是,直接输出 "error" 并结束程序。
-
解析数字:
- 由于输入中可能有空格,解析数字时需要维护一个指针或标记,提取完整的数字字符串(包括负号)。