const readline = require("readline"); const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); rl.on("line", function (line) { const ans: any[] = [], len = line.length; let i = 0, j = 0; const brackets: any = { ")": "(", "]": "[", "}": "{" }; const opsEnum: string[] = ["+", "-", "*", "/"]; while (j <= len) { if ((opsEnum.includes(line[j]) && i !== j) || (i <= len - 1 && j === len)) { // i !== j 处理前导负号的数字 (-1+2)*3-4,同时入栈数字和运算符 if (j < len) ans.push(Number(line.substring(i, j)), line[j]); // 处理最后一个数字 if (j === len) ans.push(Number(line.substring(i, j))); i = j + 1; } else if (["{", "[", "("].includes(line[j])) { ans.push(line[j]); // 左括号极端情况:{[(1 + 2 * 3 - 4) * 5 - 6] / 7 + 8} i = j + 1; } else if (line[j] in brackets) { // 当遇到右括号时 const arr: any[] = i < j ? [Number(line.substring(i, j))] : []; // i 可能指向行末,必须加 i < j 的判断 let pop = ans.pop(); // 把当前括号中的表达式提取出来 while (pop !== brackets[line[j]]) { arr.unshift(pop); pop = ans.pop(); } // 当前括号中的表达式计算后的结果入栈 ans.push(calc(arr)); // 找到下一个数字的起始位置 if (opsEnum.includes(line[j + 1])) { // 当前括号位置的下一个位置为 运算符 时,下下个位置一定是 数字 ans.push(line[j + 1]); i = j + 2; ++j; } else { // 当前括号的下一个位置可能是一个中括号、大括号、行末,如 )]} i = j + 1; while (i < len && Number.isNaN(Number(line[i]))) ++i; } } ++j; } console.log(calc(ans)); function calc(arr: any[]): number { if (arr.length === 1) return arr[0]; const ops: string[] = []; // 把操作数和运算符分组 for (let i = 0; i < arr.length; ++i) { if (arr[i].length === 1 && opsEnum.includes(arr[i])) { ops.push(arr[i]); arr.splice(i, 1); } } // 从左到右,先处理优先级高的乘、除运算 let i = 0; while (ops.includes("*") || ops.includes("/")) { while (i < ops.length) { if (ops[i] === "*" || ops[i] === "/") { const [num1, num2]: [any, any] = [arr.splice(i, 1), arr.splice(i, 1)]; arr.splice(i, 0, ops[i] === "*" ? num1 * num2 : num1 / num2); ops.splice(i, 1); break; } ++i; } } // 处理加、减运算 while (ops.length !== 0) { const [num1, num2] = [arr.shift(), arr.shift()]; const op = ops.shift(); if (op === "+") arr.unshift(num1 + num2); if (op === "-") arr.unshift(num1 - num2); } return arr[0]; } });