仿LISP运算 - 华为OD机试真题(A卷、JavaScript题解)

华为OD机试题库《C++》限时优惠 9.9

华为OD机试题库《Python》限时优惠 9.9

华为OD机试题库《JavaScript》限时优惠 9.9

针对刷题难,效率慢,我们提供一对一算法辅导, 针对个人情况定制化的提高计划(全称1V1效率更高)。

看不懂有疑问需要答疑辅导欢迎私VX: code5bug

华为OD机试真题

题目描述

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

题解

使用递归方法来解析和计算LISP表达式。具体步骤如下:

  1. 解析表达式:将输入的字符串解析成操作符和参数。参数可能是数字或其他嵌套的表达式。
  2. 递归计算:对于每个操作符,递归计算其参数的值。如果参数是嵌套的表达式,继续递归解析和计算。
  3. 处理操作:根据操作符的类型执行相应的算术操作。处理除法时,需检查除数是否为零,若为零则返回错误。
  4. 错误处理:在计算过程中,任何除数为零的情况都应立即返回错误。

JavaScript

const rl = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout,
});

var iter = rl[Symbol.asyncIterator]();

const readline = async () => (await iter.next()).value;

function evaluate(expr) {
    // 移除最外层的括号并分割
    const content = expr.slice(1, -1).trim();
    const parts = [];
    let buffer = '';
    let parenLevel = 0;

    for (const char of content) {
        if (char === '(') {
            parenLevel++;
            buffer += char;
        } else if (char === ')') {
            parenLevel--;
            buffer += char;
        } else if (char === ' ' && parenLevel === 0) {
            parts.push(buffer);
            buffer = '';
        } else {
            buffer += char;
        }
    }
    if (buffer !== '') {
        parts.push(buffer);
    }

    const op = parts[0];
    const operands = parts.slice(1);

    if (operands.length !== 2) {
        throw new Error('Invalid operands count');
    }

    const parseOperand = (operand) => {
        if (operand.startsWith('(')) {
            return evaluate(operand);
        } else {
            return parseInt(operand, 10);
        }
    };

    const a = parseOperand(operands[0]);
    const b = parseOperand(operands[1]);

    switch (op) {
        case 'add':
            return a + b;
        case 'sub':
            return a - b;
        case 'mul':
            return a * b;
        case 'div':
            if (b === 0) {
                throw new Error('Division by zero');
            }
            return Math.floor(a / b);
        default:
            throw new Error('Unknown operator');
    }
}

// Author: code5bug
(async () => {
    const input = await readline();
    try {
        const result = evaluate(input);
        console.log(result);
    } catch (e) {
        console.log('error');
    }
    rl.close();
})();

整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

什码情况

你的鼓励就是我最大的动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值