逆波兰实现四则运算

前言

写过的四则运算相关的博客:

这里使用中缀转后缀,再计算的方法来实现四则运算。

思路:在这里插入图片描述

图片来源(截图): https://www.cnblogs.com/chensongxian/p/7059802.html



代码

//
// Created by Andy Dennis on 2020/12/9.
// 使用中缀转后缀表达式来计算四则运算
//
#include <iostream>
#include <stack>
#include <cmath>

using namespace std;

int getPriority(char c);

double string2float(string s);

string infix2postfix(const string &infix);

double postfix2result(const string &postfix);

int main() {
    
    
    string infixStr = "1+((2+3)*4)/2-5";
    string postfixStr = infix2postfix(infixStr);
    double result = postfix2result(postfixStr);
    cout << "infix: " << infixStr << endl;
    cout << "postfix: " << postfixStr << endl;
    cout << "result: " << result << endl;
}

string infix2postfix(const string &infix) {
    
    
    string postfix;   // 后缀表达式
    stack<char> op;     // 保存中间结果
    for (int i = 0; i < infix.length(); i++) {
    
    
        if (infix[i] >= '0' && infix[i] <= '9') {
    
    
            // 数字直接进入结果表示
            string tempNumStr;
            while (i < infix.length() && (infix[i] >= '0' && infix[i] <= '9' || infix[i] == '.')) {
    
    
                tempNumStr += infix[i];
                i++;
            }
            //  double num = string2float(tempNumStr); 暂时不需要转换, 加入后缀表达式即可
            postfix += tempNumStr;
            postfix += " ";
        }
        if (op.empty() || op.top() == '(' || infix[i] == '(') {
    
    
            // 中间结构栈为空,栈顶是左括号,遇到左括号,则运算符直接入栈
            op.push(infix[i]);
        } else if (infix[i] == ')') {
    
    
            // 遇到左括号则一直取出中间结果栈的元素加到后缀表达式中
            while (!op.empty()) {
    
    
                char temp = op.top();
                op.pop();
                if (temp == '(') {
    
    
                    break;
                }
                postfix += temp;
                postfix += " ";
            }
        } else if (getPriority(infix[i]) > getPriority(op.top())) {
    
    
            op.push(infix[i]);
        } else {
    
     // getPriority(infix[i]) < getPriority(op.top())
            char temp = op.top();
            op.pop();
            postfix += temp;
            postfix += " ";
            // 重新用当前的运算符继续判断
            i--;
        }
    }
    while (!op.empty()) {
    
    
        char temp = op.top();
        op.pop();
        postfix += temp;
        postfix += " ";
    }
    return postfix;
}

double postfix2result(const string &postfix) {
    
    
    stack<double> numSt;
    double n1, n2;
    for (int i = 0; i < postfix.length(); i++) {
    
    
        if (postfix[i] == ' ')   // 处理一下空格
            continue;
        if (postfix[i] >= '0' && postfix[i] <= '9') {
    
    
            // 数字直接进入结果表示
            string tempNumStr;
            while (i < postfix.length() && (postfix[i] >= '0' && postfix[i] <= '9' || postfix[i] == '.')) {
    
    
                if (postfix[i] == ' ') {
    
    
                    i++;    //处理一下空格
                    continue;
                }
                tempNumStr += postfix[i];
                i++;
            }
            double num = string2float(tempNumStr);
            numSt.push(num);
        } else {
    
    
            n2 = numSt.top();
            numSt.pop();
            n1 = numSt.top();
            numSt.pop();
            if (postfix[i] == '+')
                n1 = n1 + n2;
            else if (postfix[i] == '-')
                n1 = n1 - n2;
            else if (postfix[i] == '*')
                n1 = n1 * n2;
            else if (postfix[i] == '/') {
    
    
                if (n2 > -0.00001 && n2 < 0.00001) {
    
    
                    cout << "Error! divided by zero!" << endl;
                    exit(EXIT_FAILURE);
                }
                n1 = n1 / n2;
            } else {
    
    
                cout << "undefined operation " << postfix[i] << " occur!" << endl;
                exit(EXIT_FAILURE);
            }
            numSt.push(n1);
        }
    }
    double result = numSt.top();
    numSt.pop();
    return result;
}


int getPriority(char c) {
    
    
    int priority = -1;  // -1代表错误
    if (c == '+' || c == '-')
        priority = 0;
    if (c == '*' || c == '/')
        priority = 1;
    return priority;
}


// 字符串转数字
double string2float(string s) {
    
    
    double n = 0;
    bool isXiaoShu = false; // 判断当前的数字是不是小数部分
    int xiaoShuLength = 0;  // 记录小数部分的长度
    for (int i = 0; i < s.length(); i++) {
    
    
        if (s[i] >= '0' && s[i] <= '9') {
    
    
            n = n * 10 + float(s[i] - '0');
            if (isXiaoShu)
                xiaoShuLength++;
        } else if (s[i] == '.') {
    
    
            isXiaoShu = true; //开始进入小数部分
        }
    }
    return n * 1.0 / pow(10, xiaoShuLength);
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43850253/article/details/110929643