跳转到内容
返回

js实现计算器

栈计算器

效果图

说些废话

1.界面不是重点,使用的flex布局,仿的ios的计算器界面2.代码只写了核心的算法实现(理解了你就能写出来了),想要整体的代码,大家参考给出的源码链接

本文源码

分析

1.多项运算时,运算符优先级的问题2.获取要运算的数字时处理,是个位数还是多位数的问题

原理

优先级问题

处理个位数还是多位数问题

代码实现

// 创建存储数字的栈
let nums = [];
// 存储运算符的栈
let op = [];
// 创建运算符优先级表(用对象来做)
let priority = {
  "+": 0,
  "-": 0,
  "*": 1,
  "/": 1,
};
// 比较优先级函数op1栈顶(即数组最后一个)元素,op2为当前获取到运算符
let compare = function (op1, op2) {
  if (priority[op1] > priority[op2]) {
    // 当前运算符优先级小于栈顶元素 取出栈顶运算符和nums栈顶2个数字进行运算 并将结果入栈
    let one = nums.pop();
    let two = nums.pop();
    switch (op.pop()) {
      case "+":
        // 将运算结果入栈
        nums.push(one + two);
        break;
      case "-":
        nums.push(one - two);
        break;
      case "*":
        nums.push(one * two);
        break;
      case "/":
        nums.push(one / two);
        break;
      default:
        break;
    }
    // 将该运算符入栈
    op.push(op2);
  } else {
    // 大于或者等于时 直接入栈
    op.push(op2);
  }
};
// 假设一串表达式是 1+5*6-1;
let str = "1+5*6-1";
let arr = str.split(""); // ["1", "+", "5", "*", "6", "-", "1"]
// 入口函数
var cal = function () {
  // 模拟真实点击按键获取数据入栈的过程
  arr.forEach(e => {
    // 判断当前元素是数字还是运算符
    if (isNaN(Number(e))) {
      // 运算符 比较优先级
      compare(op[op.length - 1], e);
    } else {
      // 数字 直接入栈
      nums.push(Number(e));
    }
  });
  //计算表达式结果   这里没有遵循栈的操作规则 老铁们可以自己优化下
  // 遍历op 当op内没有元素后 停止循环
  while (op.length != 0) {
    // 依次取出栈低(数组起始位置)的2个元素和符号进行运算
    // 运算完毕后 再将结果插入到第一个
    let one = nums.shift();
    let two = nums.shift();
    switch (op.shift()) {
      case "+":
        // 将运算结果插入到第一个
        nums.unshift(one + two);
        break;
      case "-":
        nums.unshift(one - two);
        break;
      case "*":
        nums.unshift(one * two);
        break;
      case "/":
        nums.unshift(one / two);
        break;
      default:
        break;
    }
  }
  // 上述操作后 数组最后就剩下一个数 即运算结果
  console.log(nums[0]);
};
cal();

总结

在最后的计算结果的地方,因为在数组中如果对第一个元素进行增删,当数组元素过多时,会很影响性能,所以这里还有很多优化的地方,后序会再更新。



上一篇
vuejs基础复习4---生命周期函数
下一篇
关于面试
×