题目
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值,整数除法仅保留整数部分。
输入: s = " 3+5 / 2 " 输出: 5
题解
第一种
我们在函数中先声明一个calculate函数,这个函数接受一个参数s,表示我们需要进行计算的算术表达式,接下来我们定义了一个辅助函数isNum,用于判断一个字符是否为数字,然后使用正则表达式去除了表达式中的空格,接着定义了一个栈stack和一个变量preSign以及一个变量num,stack用于存储运算符和数字,preSign用于记录上一个运算符,num用于记录当前数字的值,然后我们使用split方法将表达式s转换成字符数组,然后我们遍历该字符数组中的每一个字符,如果该字符是数字,我们就将其转换为数值类型并存储到变量num中,如果该字符不是数字或者已经遍历到了表达式的最后一个字符,我们就根据preSign的值将num压入栈stack中,并更新preSign和num的值,在遍历完整个表达式后,使用reduce方法计算栈stack中所有元素的和后我们将其返回出去即可
var calculate = function(s) { const isNum = (chr) => !isNaN(Number(chr)) s = s.replace(/\s/g, ''); const stack = new Array(); let preSign = '+'; let num = 0; const n = s.length; s.split('').map((chr, i)=>{ if (isNum(chr)) { num = num * 10 + Number(chr) } if (!isNum(chr) || i === n - 1) { switch (preSign) { case '+': stack.push(num); break; case '-': stack.push(-num); break; case '*': stack.push(stack.pop() * num); break; default: stack.push(stack.pop() / num | 0); } preSign = chr; num = 0; } }); return stack.reduce((pre, cur)=>pre+cur, 0); };
第二种
我们在函数中先s参数中的空格去除,我们这里使用正则表达式来实现,主要为了去除表达式中可能存在的空格,方便我们后续的计算,然后我们使用循环去判断表达式中是否还包含除法/或乘法*的运算符,如果包含我们则继续进行计算,在每次循环中,我们使用正则表达式去匹配表达式中的乘法或除法运算,并执行对应的操作,如果我们匹配到乘法或除法运算的表达式我们则将其替换为回调函数中的返回值,回调函数的参数p1、p2、p3分别表示匹配到的第一个数字、运算符、第二个数字,我们在回调函数中,通过判断运算符p2的值,如果是乘法我们则返回两个数字的乘积;如果是除法我们则使用Math.floor函数将两个数字的整除结果向下取整后返回,我们通过不断的匹配和替换,直到表达式中不再包含乘法和除法运算符,最后我们使用eval函数来计算最终的表达式结果返回即可
function calculate1(s) { s = s.replace(/\s/g, '') while (s.includes('/') || s.includes('*')) { s = s.replace(/(\d+)(\/|\*)(\d+)/, (_, p1, p2, p3) => { return p2 === '*' ? p1 * p3 : Math.floor(p1 / p3) }) } return eval(s) }