微信小程序简易计算器实现(JS实现的中缀表达式转化为后缀表达式)


微信小程序实现的计算器



前提:
首先:你要知道什么是中缀表达式,什么是后缀表达式。。。当然,知道了这个你就知道了在这里计算器实现的本质了。。。
当然,如果你只是想用这个函数接口,那你不知道这些也没有关系,因为代码将会直接给出来的,你只需要知道怎么去调用这份代码中的函数即可。。。


本质:
实现计算功能的本质其实就是将人们正常数输入的算数表达式(中缀表达式)转化为计算机可以直接识别计算的后缀表达式,计算机通过这个后缀表达式便可以计算出结果啦。。。

重点来了

此份代码是微信小程序中js的书写方式,如果您想要利用此逻辑实现一个简易的计算器,那么你可以将此份代码放到微信小程序的工具包里面,然后通过**require()**方法引入想要引用的页面即可;如果想要在前端html网页中利用此份代码实现计算逻辑,请务必合理的利用代码的调用方式,当然怎么调用函数你肯定比我清楚。。。

代码实现如下:

/*利用JS实现中缀表达式转后缀表达式并计算结果
思路:
第一步:
中缀转后缀
创建一个字符串存储后缀表达式,一个栈存储运算符
遍历中缀表达式,遇到运算符进栈,遇到数字直接添加到字符串中
进栈时,若当前运算符优先级比栈顶高,直接进栈,否则将栈顶元素添加到字符串中并
退栈,直到遇见优先级比当前运算符低的运算符时才进栈,若栈顶为‘(’,直接进栈,若
当前运算符为‘)’,将栈顶元素添加到字符串中并退栈至‘(’【注意:此时‘(’ 不进入字符
串但依旧需要将‘(’ 退栈】。最后将栈中所有运算符依次添加到字符串中,清空栈,此时
字符串即为后缀表达式

第二步:
后缀计算结果
创建一个栈存储数字

遍历后缀表达式,遇到数字进栈,遇到运算符出栈两次,将这两个数字根据响应的运算
符进行计算,将计算结果进栈。
最后栈中存下的数字即为结果。

注意:要利用这个来计算表达式的值时需要注意的是:各个算符之间的优先级关系要搞清楚

*/
/*第0步:对所有的运算符进行优先级排序*/
function Sort(operator) {
  //注意:运算符的优先级为*=/>%>+=-
  switch (operator) {
    case '+':
      return 1;
    case '-':
      return 1;
    case '%':
      return 2;
    case '*':
      return 3;
    case '/':
      return 3;
    default:
      return 0;
  }
}

/*第一步:中缀表达式转化为后缀表达式*/
function transform(expression) {
  var operator_stack = []
  //用于存储后缀表达式
  var suffix_expr = ""

  for (var i = 0; i < expression.length; i++) {

    switch (expression[i]) {
      case '(':    
        operator_stack.push('(')
        break;
      case ')':   
        while (operator_stack.length > 0 && operator_stack[operator_stack.length - 1] != '(') {
          suffix_expr += operator_stack[operator_stack.length - 1]
          let ccc = operator_stack.pop()

        }
        let ddd = operator_stack.pop()

        break;
      default:            

        if (expression[i] >= '0' && expression[i] <= '9' )
        {
       
        
        if((expression[i + 1] < '0' || expression[i + 1] > '9')&&expression[i+1]!='.'&&(i+1)<expression.length)
          {
        
            suffix_expr += expression[i]
            suffix_expr += '#'  //利用这个来分割数字

          }
        else if ((i+1)==expression.length && expression[i] >= '0' && expression[i] <= '9')
        {
          suffix_expr += expression[i]
          suffix_expr += '#'  //利用这个来分割数字
        }
          else if (expression[i+1]=='.')
          {
            
            suffix_expr+=expression[i]
            suffix_expr+=expression[i+1]
            i++
           
          }
          else {
            suffix_expr += expression[i]
          }
        }
        else if ((operator_stack.length == 0 || operator_stack[operator_stack.length - 1] == '(') || (operator_stack[operator_stack.length - 1] != '(' && Sort(expression[i]) > Sort(operator_stack[operator_stack.length - 1]))) {
          
          operator_stack.push(expression[i])

        }
        else {
          while (operator_stack.length != 0 && Sort(expression[i]) <= Sort(operator_stack[operator_stack.length - 1])) {
            var temps = operator_stack.pop()
            suffix_expr += temps

          }
          operator_stack.push(expression[i])
        }
        break;

    }
  }

  while (operator_stack.length != 0)    //将剩余的栈中的所有运算符出栈
  {
    suffix_expr += operator_stack.pop()
  }
 
  var answer=result(suffix_expr)
  return answer
}
/*第二步:由得到的后缀表达式计算表达式的值*/
function result(suffix_expr) {

  var tempNum, num1, num2
  var number = []        //用于存储数字的临时栈
  for (var i = 0; i < suffix_expr.length; i++) {

    var tempStr = ''
    if (suffix_expr[i] >= '0' && suffix_expr[i] <= '9') //当为数字时直接进栈
    {
      while (suffix_expr[i] != '#' && i < suffix_expr.length && suffix_expr[i] >= '0' && suffix_expr[i] <= '9'||suffix_expr[i]=='.') {
        tempStr += suffix_expr[i];    //存储刚刚取到的数字
        i++;
      }

      if (suffix_expr[i] != '#' && i < suffix_expr.length && suffix_expr[i] < '0' || suffix_expr[i] > '9') {
        i--;
      }
      tempNum = Number(tempStr)    //将刚取到的字符串转化为数字并存放到栈中
      number.push(tempNum)       //将转化后的数字压入栈         
    }
    else if (suffix_expr[i] != '#')  //如果没有遇到数字,而是遇到了运算符,则出栈两次,代表取出两个操作数用来计算
    {
      //取出了两个操作数
      num1 = number.pop()
      num2 = number.pop()
    }
    switch (suffix_expr[i]) {  //遇到运算符之弹出操作数之后就计算
      case '+':
        tempNum = Number(num1) + Number(num2);

        number.push(tempNum);

        break;
      case '-':
        tempNum = Number(num2) - Number(num1);
        number.push(tempNum);
        break;
      case '*':

        tempNum =( Number(num1)*10000 * Number(num2))/10000; 
        //乘以10000再除以10000的作用是使得计算结果更加准确,因为js的乘除法有误差,除法同理
        number.push(tempNum);
        break;
      case '/':
        tempNum = (Number(num2)*10000 / Number(num1))/10000;
        number.push(tempNum);
        break;
      case '%':
        tempNum = Number(num2) % Number(num1);
        number.push(tempNum);
        break;
      default: break;

    }

  }
  return number.pop();
}
module.exports = {
	count:transform                   //入口
}

对以上函数的调用方式:
由于是在微信小程序中,所以就只说微信小程序中的调用方式了。由于我是将其放在一个工具文件夹下面(当然,你可以将此直接放到当前页面的js代码中),所以需要利用require()引入,在某页面引用的具体步骤如下:

1.const caculator=require(“以上js文件的路径”)
2.var result=caculator.transform(“要计算的算数表达式”).

*2.1**例如:var result=caculator.transform("(3.45)+2")

上面要计算的****”算数表达式****“就是由页面中用户点击输入而获得的表达式了,当然这份对于用户输入的算数表达式的转换逻辑就需要自己实现了。
示例图如下:
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值