ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

计算公式 - 四则运算实现

2021-04-17 23:04:36  阅读:227  来源: 互联网

标签:中缀 括号 实现 四则运算 栈顶 后缀 计算公式 表达式 运算


计算公式 - 四则运算实现

要对公式进行运算,首先需要实现基础的四则运算(包含符号()+-*/),用于解析一个字符串的计算式子(如:'(6+2)/4-2')。算法思路如下:

第一步:中缀表达式转后缀表达式

中缀表达式是利于人理解的表达方式,而后缀表达式更方便计算机的运算。

<section>
  (或中缀记法)是一个通用的算术或逻辑公式表示方法, 操作符是以中缀形式处于操作数的中间(例:3 + 4),中缀表达式是人们常用的算术表示方法。
	与前缀表达式(例:+ 3 4)或后缀表达式(例:3 4 +)相比,中缀表达式不容易被计算机解析,但仍被许多程序语言使用,因为它符合人们的普遍用法。
与前缀或后缀记法不同的是,中缀记法中括号是必需的。计算过程中必须用括号将操作符和对应的操作数括起来,用于指示运算的次序。
例:
(1)8+4-6*2用后缀表达式表示为:8 4+6 2*-
(2)2*(3+5)+7/1-4用后缀表达式表示为:235+*71/+4-
</section>

所以首先将中缀表达式转换成后缀表达式。这个过程需要一个辅助处理的栈,从左到右扫描表达式里的每一个字符,执行以下操作:

  • 为数字,直接添加到后缀表达式末尾
  • 为 +-*/ 运算符,弹出所有优先级大于或者等于该运算符的辅助栈顶元素到后缀表达式中,然后将该运算符入栈
  • 为左括号(,直接入栈
  • 为右括号),弹出栈顶元素到后缀表达式中,直到匹配到第一个左括号,括号不输出到后缀表达式

遍历完成后,将辅助栈中的元素输出,则得到后缀表达式。

说明:操作符优先级为: () <  +- <  */

以A*(B-C)/D为例,处理过程如下:

 

   function infixToPostfix(infix, postfix) {
            let postfixHelper = Stack();
            for (let i = 0; i < infix.length; i++) {
                let c = infix[i]
                if (!isOper(c)) { // 处理操作数
                    let operands = ""
                    while (i < infix.length && !isOper(infix[i])) {
                        operands += infix[i++]
                    }
                    postfix.push(operands)
                    i--;
                } else { // 处理操作符做出处理
                    handlerSymbol(c, postfixHelper, postfix)
                }
            }
            console.log(postfixHelper)
            // 如果输入结束,将栈内元素全部弹出,加入后缀表达式中
            while (!postfixHelper.empty()) {
                let c = postfixHelper.top()
                postfix.push(c)
                postfixHelper.pop()
            }
        }

第二步:计算后缀表达式

计算后缀表达式,同样需要一个辅助处理的栈,从左到右遍历字符,遇到操作数压入辅助栈中;遇到操作符则从栈顶取出两个元素,第一个为右运算数,第二个为左运算数(注意这个顺序在除法中是结果相关的)。运算后的结果入栈。遍历完成后,辅助栈顶的元素则为所求。

 // 计算后缀表达式
        function calcPostFix(postfix, data) {
            let helperStack = Stack()
            for (let i = 0; i < postfix.length; i++) {
                let c = postfix[i]

                // 如果是操作数,压入栈中
                if (!isOper(c)) {
                    let op = Number(c); // 数值
                    helperStack.push(op)
                } else {
                    // 如果是操作符,从栈中弹出元素进行计算
                    let op1 = helperStack.top()
                    helperStack.pop()
                    let op2 = helperStack.top()
                    helperStack.pop()
                    if (op1 === null || op2 === null) {
                        helperStack.push(null)
                    } else {

                        switch (c) {
                            case "+":
                                helperStack.push(op2 + op1)
                                break
                            case "-":
                                helperStack.push(op2 - op1)
                                break
                            case "*":
                                helperStack.push(op2 * op1)
                                break
                            case "/":
                                helperStack.push(op2 / op1) // 注意是op2(op)op1而不是op1(op)op2
                                break
                        }
                    }
                }
            }
            return helperStack.top()
        }

标签:中缀,括号,实现,四则运算,栈顶,后缀,计算公式,表达式,运算
来源: https://blog.51cto.com/u_15166492/2714370

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有