JavaScript 实现计算器,进行加减乘除运算并处理括号关系

Tips: 我的实例在Vue环境下进行,我给的代码中调用其他函数时,通过this找到。如果读者使用原生JavaScript,则需要删除this。

正文开始

1. 前端页面展示如下

用户在Input输入框输入计算表达式,点击计算按钮,即可完成计算,后展示在下方。

2. 代码逻辑

2.1 用户输入的为字符串,首先处理字符串成数字和运算符数组

// str 即为input输入的数据
function sliceCountStr(str) {
      let arr = []; // 记录分割计算表达式
      for (let i = 0; i < str.length; i++) {
        let item = str.charAt(i);
        let num = item;
        if (/[\d|\.]/.test(item)) {
          let j = i + 1;
          for (; j < str.length - 1; j++) {
            let otherItem = str.charAt(j);
            if (!/[\d|\.]/.test(otherItem)) {
              break;
            }
          }
          num = str.slice(i, j);
          i = j - 1;
          num = +num;
        }
        arr.push(num);
      }
      return arr;
    },

2.2 设置数字栈和运算符栈,进行入栈和出栈操作

// arr 即为上一步处理好的数组
function countHandle(arr) {
      let charArr = [],
        numArr = [];
      for (let i = 0; i < arr.length; i++) {
        if (typeof arr[i] == 'number') {
          numArr.push(arr[i]);
        } else {
          if (charArr.length) {
            // 步骤1
            // 如果当前的运算符的优先级比栈顶的优先级低或相等,就说明需要把前面的值全部计算好
            // 存储运算符的栈要一直出栈,直到栈为空或当前的字符的优先级比栈顶的优先级高
            while (this.isPop(arr[i], charArr[charArr.length - 1])) {
              let t2 = numArr.pop();
              let t1 = numArr.pop();
              let char = charArr.pop();
              this.handleCalculation(numArr, t1, t2, char);
            }
            // 当前运算符为右括号
            if (arr[i] == ')') {
              // 取栈顶运算符
              let st = charArr[charArr.length - 1];
              // 步骤2
              // 遇到右括号也要一直出栈,直到遇到左括号
              while (st != '(') {
                let t1, t2;
                let char = charArr.pop();
                if (char != '(') {
                  t2 = numArr.pop();
                  t1 = numArr.pop();
                  this.handleCalculation(numArr, t1, t2, char);
                }
                st = char;
              }
            }
            // 运算符不为右括号
            if (arr[i] != ')') {
              charArr.push(arr[i]);
            }
          } else {
            // 步骤3
            // 运算符栈为空,直接入栈
            charArr.push(arr[i]);
          }
        }
      }
      // 步骤4
      // 最后运算符栈如果还有字符,要一直出栈直到为空
      while (charArr.length) {
        let t2 = numArr.pop();
        let t1 = numArr.pop();
        let char = charArr.pop();
        this.handleCalculation(numArr, t1, t2, char);
      }
      return numArr[0];
    },

2.3 基本操作函数

// 基本加减乘除运算处理
    function handleCalculation(numArr, num1, num2, char) {
      if (char == '+') {
        numArr.push(num1 + num2);
      } else if (char == '-') {
        numArr.push(num1 - num2);
      } else if (char == '*') {
        numArr.push(num1 * num2);
      } else if (char == '/') {
        numArr.push(num1 / num2);
      }
    },
    // 判断运算符的优先级,是否出栈进行计算
    function isPop(char1, char2) {
      // 运算符栈为空
      if (!char2) {
        return false;
      }
      // 运算符优先级相同
      if ((char1 == '+' || char1 == '-') && (char2 == '+' || char2 == '-')) {
        return true;
      }
      // 前者运算符优先级比后者低
      if ((char1 == '+' || char1 == '-') && (char2 == '*' || char2 == '/')) {
        return true;
      }
      // 运算符优先级相同
      if ((char1 == '*' || char1 == '/') && (char2 == '*' || char2 == '/')) {
        return true;
      }
      // 前者运算符优先级比后者高
      if ((char1 == '*' || char1 == '/') && (char2 == '+' || char2 == '-')) {
        return false;
      }
    }

3. 展示结果

posted @ 2022-08-04 16:45  青柠i  阅读(1161)  评论(4编辑  收藏  举报