华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
一、题目描述
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 |
二、输入描述
输入为长度不超过512的字符串,用例保证了无语法错误
三、输出描述
输出计算结果或者“error”。
四、解题思路
- 定义数字栈numStack,操作符栈operatorStack;
- 遍历输入的字符串input;
- 如果是(,则操作符入栈;
- 如果是计算标识符),数字入栈、弹出num2、弹出num1,通过加减乘除标识符计算;
- 如果是空格,则数字入栈
- 输出数字栈最后数值。
五、Python算法源码
# 计算LISP表达式的结果
def calculate_lisp(expr: str) -> int:
# 初始化数字栈和操作符栈
num_stack = []
op_stack = []
# 指针和长度
i = 0
length = len(expr)
# 辅助函数:执行运算
def do_calculate():
op = op_stack.pop()
num2 = num_stack.pop()
num1 = num_stack.pop()
if op == "add":
num_stack.append(num1 + num2)
elif op == "sub":
num_stack.append(num1 - num2)
elif op == "mul":
num_stack.append(num1 * num2)
elif op == "div":
if num2 == 0:
return "error"
num_stack.append(num1 // num2)
# 主循环处理表达式
while i < length:
char = expr[i]
if char == '(':
# 处理操作符
op_stack.append(expr[i+1:i+4])
i += 4
elif char == ')':
# 计算结果
do_calculate()
elif char.isdigit() or char == '-':
# 处理数字
j = i + 1
while j < length and (expr[j].isdigit() or expr[j] == '-'):
j += 1
num_stack.append(int(expr[i:j]))
i = j - 1
i += 1
return num_stack[0]
# 测试代码
if __name__ == "__main__":
test_cases = [
"(mul 3 -7)",
"(add 1 2)",
"(sub (mul 2 4) (div 9 3))",
"(div 15 5)",
"(mul (add 1 2) (sub 4 2))"
]
for test in test_cases:
print(f"Input: {test}")
print(f"Output: {calculate_lisp(test)}")
print()
六、JavaScript算法源码
/**
* 计算LISP表达式的结果
* @param {string} expr 输入的LISP表达式
* @returns {number} 计算结果
*/
function calculateLisp(expr) {
// 初始化栈
const numStack = [];
const opStack = [];
// 辅助函数:执行运算
function doCalculate() {
const op = opStack.pop();
const num2 = numStack.pop();
const num1 = numStack.pop();
switch(op) {
case 'add':
numStack.push(num1 + num2);
break;
case 'sub':
numStack.push(num1 - num2);
break;
case 'mul':
numStack.push(num1 * num2);
break;
case 'div':
if (num2 === 0) return "error";
numStack.push(Math.floor(num1 / num2));
break;
}
}
// 主循环处理表达式
for (let i = 0; i < expr.length; i++) {
const char = expr[i];
if (char === '(') {
opStack.push(expr.substr(i + 1, 3));
i += 3;
} else if (char === ')') {
doCalculate();
} else if (/[\d-]/.test(char)) {
let num = '';
while (i < expr.length && /[\d-]/.test(expr[i])) {
num += expr[i++];
}
numStack.push(parseInt(num));
i--;
}
}
return numStack[0];
}
// 测试代码
const testCases = [
"(mul 3 -7)",
"(add 1 2)",
"(sub (mul 2 4) (div 9 3))",
"(div 15 5)",
"(mul (add 1 2) (sub 4 2))"
];
testCases.forEach(test => {
console.log(`Input: ${test}`);
console.log(`Output: ${calculateLisp(test)}`);
console.log();
});
七、C算法源码
/**
* 计算LISP表达式的结果
* @param {string} expr 输入的LISP表达式
* @returns {number} 计算结果
*/
function calculateLisp(expr) {
// 初始化栈
const numStack = [];
const opStack = [];
// 辅助函数:执行运算
function doCalculate() {
const op = opStack.pop();
const num2 = numStack.pop();
const num1 = numStack.pop();
switch(op) {
case 'add':
numStack.push(num1 + num2);
break;
case 'sub':
numStack.push(num1 - num2);
break;
case 'mul':
numStack.push(num1 * num2);
break;
case 'div':
if (num2 === 0) return "error";
numStack.push(Math.floor(num1 / num2));
break;
}
}
// 主循环处理表达式
for (let i = 0; i < expr.length; i++) {
const char = expr[i];
if (char === '(') {
opStack.push(expr.substr(i + 1, 3));
i += 3;
} else if (char === ')') {
doCalculate();
} else if (/[\d-]/.test(char)) {
let num = '';
while (i < expr.length && /[\d-]/.test(expr[i])) {
num += expr[i++];
}
numStack.push(parseInt(num));
i--;
}
}
return numStack[0];
}
// 测试代码
const testCases = [
"(mul 3 -7)",
"(add 1 2)",
"(sub (mul 2 4) (div 9 3))",
"(div 15 5)",
"(mul (add 1 2) (sub 4 2))"
];
testCases.forEach(test => {
console.log(`Input: ${test}`);
console.log(`Output: ${calculateLisp(test)}`);
console.log();
});
八、C++算法源码
#include <iostream>
#include <stack>
#include <string>
using namespace std;
// 计算LISP表达式的结果
int calculateLisp(string expr) {
// 初始化栈
stack<int> numStack;
stack<string> opStack;
// 主循环处理表达式
for (int i = 0; i < expr.length(); i++) {
char ch = expr[i];
if (ch == '(') {
// 处理操作符
opStack.push(expr.substr(i + 1, 3));
i += 3;
} else if (ch == ')') {
// 执行运算
int num2 = numStack.top(); numStack.pop();
int num1 = numStack.top(); numStack.pop();
string op = opStack.top(); opStack.pop();
if (op == "add") numStack.push(num1 + num2);
else if (op == "sub") numStack.push(num1 - num2);
else if (op == "mul") numStack.push(num1 * num2);
else if (op == "div") {
if (num2 == 0) {
cout << "error" << endl;
return 0;
}
numStack.push(num1 / num2);
}
} else if (isdigit(ch) || ch == '-') {
// 处理数字
string numStr;
while (i < expr.length() && (isdigit(expr[i]) || expr[i] == '-')) {
numStr += expr[i++];
}
numStack.push(stoi(numStr));
i--;
}
}
return numStack.top();
}
int main() {
// 测试用例
string testCases[] = {
"(mul 3 -7)",
"(add 1 2)",
"(sub (mul 2 4) (div 9 3))",
"(div 15 5)",
"(mul (add 1 2) (sub 4 2))"
};
for (const auto& test : testCases) {
cout << "Input: " << test << endl;
cout << "Output: " << calculateLisp(test) << endl;
cout << endl;
}
return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。