现已知一个字符串是由正整数和加减乘除四个运算符(+ - * /)组成。

例如存在字符串 const str = '11+2-3*4+5/2*4+10/5',现在需要将高优先级运算,用小括号包裹起来,例如结果为 '11+2-(3*4)+(5/2*4)+(10/5)'。注意可能会出现连续的乘除运算,需要包裹到一起。

请用 javascript 实现这一过程

参考答案

介绍一种只需遍历一次的实现方式,思路比较简单,主要用到了2个临时变量,分别用于记录当前是否在高优先级运算范围和临时值,然后根据不同优先级的运算符进行不同的处理操作。

具体的代码如下:

function addBrackets(expression) { const resultArr = [] // 定义运算符 const symbolArr = ['+', '-', '*', '/'] // 定义高优先级运算符 const highLevelSymbolArr = ['*', '/'] // 判断某个字符串是否是运算符 const isSymbolFn = (str) => symbolArr.includes(str) // 判断某个字符串是否是高优先级运算符 const isHighLevelSymbolFn = (str) => highLevelSymbolArr.includes(str) // 输入表达式的长度 const expLen = expression.length // 标记当前的遍历是否处于高优先级运算符范围 let isInBracket = false // 记录临时值 let currentNum = '' for (let i = 0; i < expLen; i++) { const isSymbol = isSymbolFn(expression[i]) const isHighLevelSymbol = isSymbol && isHighLevelSymbolFn(expression[i]) // 处理当前字符是运算符的场景 if (isSymbol) { //处理当前字符是高优先级运算符 if (isHighLevelSymbol) { // 如果当前没有被标记为高优先运算符,就在前面加个括号 if (!isInBracket) { currentNum = '(' + currentNum } // 修改标记状态 isInBracket = true currentNum += expression[i] } else { // 普通运算符 if (isInBracket) { // 如果之前已经在高优先级运算符范围,就需要标记结束 resultArr.push(currentNum + ')') isInBracket = false } else { resultArr.push(currentNum) } resultArr.push(expression[i]) currentNum = '' } } else { // 如果是数字,就直接进行记录 currentNum = currentNum + expression[i] } } if (currentNum) { resultArr.push(currentNum + (isInBracket ? ')' : '')) } return resultArr.join('') }

另外还可以使用滑动窗口的思路来实现:

使用正则实现(2022/10/30更新)

有小伙伴提供了一种正则表达式的实现方式,供大家参考:

let text = '11+2-34+5/24+10/5+10/512'; text.match(/([0-9]{1,}[*|/]){1,}[0-9]{1,}/g).forEach((item)=>{ text = text.replace(item,`(${item})`) }) console.log(text); // '11+2-34+(5/24)+(10/5)+(10/512)'

以上答案由“前端面试题宝典”收集、整理,PC端访问地址: https://fe.ecool.fun/