表达式求值 (栈应用)

简单计算器

Description

计算一个算术表达式的值。(式子中每个数都是一位数,且除法运算时整除,即3/2=1。输入数据保证每个表达式合法。)

Input

有多组测试样例。一个算术表达式占一行。

Output

输出表达式的值。

Sample Input

1+1
2*3

Sample Output

2
6

分析:就是一个含有加减乘除的表达式,并且不含有括号,计算其值。明明是很简单的表达式求值,愣是让我水了几个小时,也是醉了。。。看来真是老了

表达式求值:1、先按照计算法则,给出各运算符的优先级,这个是为了比较两个相邻运算符应该先算哪一个。

2、接下来就是真正的比较计算了,总体的比较思想是开两个栈,一个用来存数字(题目比较水,只是一位的数字),一个用来存运算符。

3、从头到尾扫描一遍表达式,逐个读入数字或运算符,如果是数字,则直接压入数字栈即可;要是运算符,则要考虑以下几种情况:

1.运算符栈为空时,直接进栈即可。

2.若不为空,则比较当前运算符和运算符栈顶运算符的优先级,若栈顶的大,就代表它的优先级比较大,我们就要先把栈顶运算符弹出栈,同时从数字栈中弹出栈顶的两个数字,因为这两个数字就是运算符栈顶元素的两个操作数(这个如果不懂得话,可以手动模拟一下操作步骤,即可明白其间的关系),这点要注意,由于栈的特点,我们取出的数字顺序,是跟原来在运算符两边的位置是相反的,所以计算的时候要调过来。再把计算出的结果压入数字栈。

3.重复步骤3.2,直到当前运算符的优先级大于运算符栈顶运算符的优先级,这时,我们再把当前等待入栈的运算符入栈。

4、重复步骤2,直到表达式扫描完为止。

5、最后,运算符栈里剩的就是优先级相等的运算符了,我们只需要把它们一个一个取出来,按照顺序算出来即可。这个顺序,比上面的简单很多,每次从运算符栈顶弹出一个运算符op,再从数字栈里依次弹出两个数a,b,那么最后计算b  op  a的值,再将其放入数字栈中,直到运算符栈为空的时候,刚好我们的数字栈中只剩下了一个元素(因为每个运算符都是两个操作数,但是所有的都相邻排列的,所以所有的操作数恰好比运算符多1个),这个就是我们表达式的最终结果。

AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <stack>
using namespace std;
#define INF 0x7fffffff
#define LL long long
#define LLL(a, b)  a<<b
#define RRR(a, b)  a>>b
#define MID(a, b)  a+(b-a)/2
const int maxn = 10000000 + 10;

int cal(int x, int y, char p){              //计算x op y的值
    if(p == '*') return x * y;
    else if(p == '/') return x / y;
    else if(p == '+') return x + y;
    else return x - y;
}

int main(){
    #ifdef sxk
        freopen("in.txt", "r", stdin);      //不用看,从文件读入用的,跟题目无关
    #endif // sxk

    int n;
    int pri[300];
    string s;
    memset(pri, 0, sizeof(pri));            //初始化优先级数组
    pri['*'] = pri['/'] = 3;                //设定运算符的优先级
    pri['+'] = pri['-'] = 1;
    while(cin >> s){                        //读入表达式
        stack<int> num;                     //数字栈
        stack<char> op;                     //运算符栈
        int len = s.size();
        for(int i=0; i<len; i++){
            if(s[i] >= '0' && s[i] <= '9') num.push(s[i] - '0');    //是数字,直接压入数字栈
            else{                                                   //是运算符
                if(!op.size()) op.push(s[i]);                       //运算符栈空,直接入栈
                else{
                    while(pri[ s[i] ] <= pri[ op.top() ]){          //循环判断,把栈顶优先级不小于当前运算符优先级的运算符全部弹出栈
                        int x = num.top(); num.pop();               //弹出两个数字
                        int y = num.top(); num.pop();
                        char c = op.top(); op.pop();                //弹出运算符
                        num.push(cal(y, x, c));                     //把计算结果压入数字栈
                        if(op.size() == 0) break;                   //一定要注意,不判空的话,会报Runtime Erro
                    }
                    op.push(s[i]);                                  //再把当前待入栈运算符入栈
                }
            }
        }
        while(op.size()){                    //最后的计算
            int x = num.top(); num.pop();
            int y = num.top(); num.pop();
            char c = op.top(); op.pop();
            num.push(cal(y, x, c));
        }
        printf("%d\n", num.top());          //栈顶元素,即为表达式的最终结果
    }
    return 0;
}
时间: 2024-08-05 17:29:23

表达式求值 (栈应用)的相关文章

表达式求值 (栈) 用C++实现

1 #include <cstdio> 2 3 #include <cstdlib> 4 5 #include <cmath> 6 7 #include <stack> 8 9 #include <cstring> 10 11 using namespace std; 12 13 14 15 char Precede(char a, char b) { //判断运算符优先级 16 17 int i, j; 18 19 char Table[8][

表达式求值--栈

用栈的方式,将中缀转为后缀,再进行求值.另外附加括号匹配的方法 1 public class PostfixExpression { 2 3 public static int lastvalue(String str){ //后缀表达式求值,传入空格分割的字符串 4 Stack<Integer> stack = new Stack<Integer>(); 5 String[] data = str.split(" "); 6 7 for(int i = 0;i

Python解析 算数表达式求值 栈的使用

使用Python实现一种算数表达式求值的算法,模拟这种使用栈的方式,这是由E.W.Dijkstra在20世纪60年代发明的一种非常简单的算法.代码模拟仅仅表现一种编程思想,代码的逻辑并不完全: if __name__ == "__main__": cal_str = input("请输入算数表达式(e.g.(((1+2)*(3+5))+2), 只适合简单的算数表达式):") num_stack = [] symbol_stack = [] for chr in ca

hdu1237 表达式求值--栈

简单计算器 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 24273    Accepted Submission(s): 8794 Problem Description 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. Input 测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整

数据结构(7)----栈与队列之栈的应用四则运算表达式求值

栈与队列之栈的应用四则运算表达式求值 栈在四则运算表达式求值的应用为逆波兰表达式(后缀表达式) 普通算式(中缀表达式):9 + (3 - 1) * 3 + 10 / 2     ---(1) 逆波兰表达式(后缀表达式):9 3 1 - 3 * + 10 2 /         ---(2) 1:逆波兰表达式的计算规则 从左到右遍历表达式的每个数字和符号,遇到数字就进栈,遇到符号,就将处于栈顶的两个数字出栈,进行运算,再把运算结果进栈,一直到最终获得结果.接下来我们以(2)式为例:

中缀表达式求后缀,再由后缀表达式求值

人:中缀表达式 计算机:后缀表达式 需要进行中缀转后缀,再计算.无论哪一步都需栈: 对于(3 + 4) × 5 - 6 一 中缀转后缀 涉及的栈用来存储符号如"+ - × / ( )" 思想: 遇见数字输出:遇见符号入栈 当空栈或者符号是左括号时直接入栈 ; 当是运算符时将要入栈的符号需要大于栈内符号否在现将栈内比该运算符大或者等的出栈输出,然后再入栈; 当运算符是右括号时,将栈内直到第一个左括号的符号出栈,并输出非括号的符号 算法: //中缀表达式改成后缀表达式 void mid2a

数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值

一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚,所以很多需要自己揣摩.这也体现了算法和程序设计语言的特点,算法更侧重本质的描述,而任何编程语言都要照顾到实现的细节以及数据类型等语法方面的需求. 表达式求值: [编码中....] 二.头文件 迷宫求解: 1 //3_2_maze.h 2 /** 3 author:zhaoyu 4 email:[em

栈的两个应用:括号匹配的检验和表达式求值

1.     括号匹配的检验 假设表达式中含有3种括号:(),[],{},其嵌套的顺序随意.检验括号是否匹配. 基本思想:在算法中设置一个栈,每读入一个括号,若是右括号,则或者与栈顶匹配的左括号相互消解,或者是不合法的情况:若是左括号,则直接压入栈中.若括号匹配,在算法的开始和结束时,栈都应该是空的. 代码: /* * 判断表达式中的括号是否匹配,匹配输出Yes,否则输出No * {(zhang)+[lei]+{lei}={zhangleilei}} -> Yes * {(zhang)+[lei

NYOJ35 表达式求值 【栈】

表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧. 比如输入:"1+2/4=",程序就输出1.50(结果保留两位小数) 输入 第一行输入一个整数n,共有n组测试数据(n<10). 每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以"

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

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