c++用栈实现算术表达式的计算

用栈将算术表达式转换成后缀表达式的形式大家应该不陌生了,但是我在实现计算的时候却发现坑还是不少。

题目描述: 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。

输入描述: 测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。

输出描述: 对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。

示例1

输入

1 + 2

4 + 2 * 5 - 7 / 11

0

输出

3.00

13.36

做这题必须注意几个问题:

  • 当栈里没有运算符的时候,直接对栈顶和字符串读取到的运算符进行比较会出错,因此这里在一开始就往栈里压入了一个我们设计的符号‘#‘
  • 当我们遍历字符串的时候,遇到数字要格外注意,因为此时一切都是字符形式了,比如说输入11就会变成两个字符1,因此我们在读取的时候要进行判断,确保所有连在一起的数字字符都读到了,而不是只读到了第一个字符。
  • 当我们遍历完字符串的时候,很有可能栈里还留有没处理的运算符,因此我们需要继续处理栈里的操作符,这里在字符串后面加入了符号\\(是很巧妙的,\\\)的优先级比‘#‘高,比其他符号低,因此这保证了当读到字符\\(时,它一定比栈顶出现的所有字符优先级高(除了它自己和‘#‘),这样就可以让栈里剩下的运算符一个一个弹出来,至到处理结束,栈顶为‘\#‘,压入\\\)。

具体代码如下:

#include<iostream>
#include<stack>
#include<string>
#include<stdio.h>
#include<cctype>
using namespace std;

/**
 * 比较操作符优先级的函数

 */
int OperPrecedence(char a){
    if(a == ‘/‘ || a == ‘*‘){
        return 3;
    }else if(a == ‘+‘ || a == ‘-‘ ){
        return 2;
    }else if(a == ‘$‘){
        return 1;
    }else if(a == ‘#‘){
        return 0;
    }

}

/**
 * 实现运算
 */

double operNums(char oper, double num1, double num2){
    if(oper == ‘+‘){
        return num1 + num2;
    }else if(oper == ‘-‘){
        return num1 - num2;
    }else if(oper == ‘*‘){
        return num1 * num2;
    }else if(oper == ‘/‘){
        return num1 / num2;
    }
}

/**
 * 实现遇到数字往后移动直到数字确定
 */

int getNum(string str, int &index){
    string num = "";
    while(isdigit(str[index])){
        num += str[index];
        index ++;
    }

    return atoi(num.c_str());
}
int main(){
    stack<char> operStack;
    stack<double> numStack;
    string str;
    char oper;
    double num1;
    double num2;
    double sum = 0;
    int index = 0, preceResult;
    operStack.push(‘#‘);
    while (getline(cin, str))
    {

        str += ‘$‘;
        if(str[0] == ‘0‘){

            break;
        }

        while(index < str.size()){

        if(str[index] == ‘ ‘){
            index++;
        }
        else if(isdigit(str[index])){
            //数字
            numStack.push(getNum(str, index));
        }else
        {
            //操作符
            //比较优先级

            if(OperPrecedence(operStack.top()) < OperPrecedence(str[index])){
                operStack.push(str[index]);
                index++;
            }else{
                num2 = numStack.top();
                numStack.pop();
                num1 = numStack.top();
                numStack.pop();
                oper = operStack.top();
                operStack.pop();
                numStack.push(operNums(oper, num1 ,num2));

            }

        }

        }
        // std::cout << "sum="<<sum << endl;
        printf("%.2f\n", numStack.top());
        index = 0;

    }

}

原文地址:https://www.cnblogs.com/yuyuan-bb/p/12614656.html

时间: 2024-10-11 15:00:59

c++用栈实现算术表达式的计算的相关文章

使用栈完成算术表达式的计算

前言:本篇文章讲解如何利用栈,完成一个简单的算术表达式的计算过程.为了简单起见,首先假设操作数是整数,而运算符为四种类型:+.-.*./ 基本思路:为了完成算术表达式的计算,用到了两个栈,一个用于存放操作数,另一个用于存放操作符. 假设:程序中定义了两个栈:operandStack(用来存放操作数).operatorStack(用于存放操作符). 在处理操作数和操作符之前,首先将它们压入栈中.当要处理一个操作符时,从operatorStack中将它弹出,然后将它应用在来自operandStack

运用栈把算术表达式+,-,*,/,%(中缀表达式)转换成后缀表达式并且计算出值

原理: 1.首先判断是数值还是符号,如果是数值放进字符数组以#表示结束, 2.如果是符号,放进栈, 3.每个符号之间要比较优先级,如果栈顶符号优先级低,符号进栈,如果相等(即“(” “)”)出栈,栈顶符号优先级高,栈顶元素出栈进入字符数组,得到后缀表达式 4.计算后缀表达式,判断是数字还是符号.直到遇到符号,将前面的数字计算后放进栈,一直重复,知道“\0” 代码(局限用整数,因为有模运算,若要任何类型的代码,我的blog有) 1 #include <stdio.h> 2 #include &l

05_2.栈的应用--表达式的计算和变换

后缀表达式的计算: class ESStack(SStack): """SStack参考05.栈""" def depth(self): return len(self._elems) def suf_exp_evaluator(exp): """后缀表达式计算""" operators = "+-*/" st = ESStack() for x in exp: if

栈应用 - 后缀表达式的计算

有关栈API详情參看我的还有一篇博文:栈的链式存储 - API实现 遍历后缀表达式中的数字和符号 对于数字:进栈 对于符号: 从栈中弹出右操作数 从栈中弹出左操作数 依据符号进行运算 将运算结果压入栈中 遍历结束:栈中的唯一数字为计算结果 #include <stdio.h> #include "LinkStack.h" int isNumber3(char c) { return ('0' <= c) && (c <= '9'); } int

Go语言用栈实现算术表达式

将中序表达式转成后序表达式,再通过后序表达式计算出值. package main //表达式 //author:Xiong Chuan Liang //date:2015-2-2 import ( "fmt" "github.com/xcltapestry/xclpkg/algorithm" "strconv" "errors" ) func main(){ // 中序表达式 后序表达式 // a+b = ab+ // (a+

安卓利用栈和算术表达式优先级实现进阶版计算器

先po上具体的源代码 简单的xml文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="

双栈计算算术表达式

1.介绍 算术表达式的计算,是比较常见的问题,但这个问题的背后隐藏着栈的思想. 这里就介绍使用两个栈来计算表达式的方法. 2. 算法 2.1 定义: a) 建立两个栈: 一个是数据栈dataStak,用于存放数据: 一个是符号栈operatorStack,用于存放运算符: b) 建立运算符号之间的优先级表,用于比较两个符号之间的优先级: 优先级定义为三种运算结果:>(表示高于),<(表示低于),=(表示相等): 并且对于"("与")",认为两者的优先级相

栈的应用—算术表达式求值

例三.算术表达式求值 1.问题描述 当一个算术表达式中含有多个运算符,且运算符的优先级不同的情况下,如何才能处理一个算术表达式????? 2.思路 首先我们要知道表达式分为三类:  ①中缀表达式:a+(b-c/d)*e ②前缀表达式+a*-be ③后缀表达式abcd/-e*+ 由于运算符有优先级,所以在计算机中计算一个中缀的表达式非常困难,特别是带括号的更麻烦,而后缀表达式中既无运算符优先又无括号的约束问题因为在后缀表达式中运算符出现的顺序正是计算的顺序,所以计算一个后缀的表达式更简单.所以,可

爪哇国新游记之二十二----算术表达式计算求值

代码: import java.util.ArrayList; import java.util.List; // 辅助类 class Item{ String value; boolean isNumber; public Item(String value,boolean isNumber){ this.value=value; this.isNumber=isNumber; } public Item(char c,boolean isNumber){ this.value=String.