中缀表达式求值 C++ Stack

给一个包含小数的中缀表达式 求出它的值

首先转换为后缀表达式然后利用stack求出值

转换规则:

如果字符为‘(‘  push

else if 字符为 ‘)‘

  出栈运算符直到遇到‘(‘

else if 字符为‘+’,’-‘,’*‘,’/‘

  {

    if 栈为空或者上一个运算符的优先级小于当前运算符

      push

    else

      {

        运算符优先级小于等于栈顶运算符的优先级,出栈

        然后!将当前运算符入栈!

      }

  }

代码

  

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<queue>
#include<deque>
#include<iomanip>
#include<vector>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<fstream>
#include<memory>
#include<list>
#include<string>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAXN  1100
#define L 31
#define INF 1000000009
#define eps 0.00000001
/*
1.000+2/4=
((1+2)*5+1)/4=
首先把中缀表达式转换为后缀表达式!(注意点运算符求值)
转换后的结果用一个string vector来表示
然后从前到后求值,pop两个数字 计算结果然后插入到stack中
*/
string str;
vector<string> trans;
stack<char> S;
stack<float> cal;
map<char, int> pri;
void Read()
{
    string tmp;
    trans.clear();
    while (!S.empty())
        S.pop();
    while (!cal.empty())
        cal.pop();
    for (int i = 0; i < str.size() - 1; i++)// 特殊考虑(  )   .
    {
        if (str[i] == ‘(‘)
        {
            if (!tmp.empty())
            {
                trans.push_back(tmp);
                tmp.clear();
            }
            S.push(str[i]);
        }
        else if (str[i] == ‘)‘)
        {
            if (!tmp.empty())
            {
                trans.push_back(tmp);
                tmp.clear();
            }
            while (!S.empty() && S.top() != ‘(‘)
            {
                string ttt = "";
                ttt.push_back(S.top());
                trans.push_back(ttt);
                S.pop();
            }
            if (!S.empty() && S.top() == ‘(‘)
                S.pop();
        }
        else if (str[i] == ‘+‘ || str[i] == ‘-‘ || str[i] == ‘*‘ || str[i] == ‘/‘)
        {
            if (!tmp.empty())
            {
                trans.push_back(tmp);
                tmp.clear();
            }
            if (S.empty() || pri[S.top()]<pri[str[i]])
            {
                S.push(str[i]);
                continue;
            }
            else
            {
                while (!S.empty() && pri[S.top()] >= pri[str[i]])
                {
                    string ttt = "";
                    ttt.push_back(S.top());
                    trans.push_back(ttt);
                    S.pop();
                }
                S.push(str[i]);
            }
        }
        else
        {
            tmp.push_back(str[i]);
        }
    }
    if (!tmp.empty())
    {
        trans.push_back(tmp);
        tmp.clear();
    }
    while (!S.empty())
    {
        string ttt = "";
        ttt.push_back(S.top());
        trans.push_back(ttt);
        S.pop();
    }
}
float solve()//计算转化出的后缀表达式的值
{
    while (!cal.empty())
        cal.pop();
    for (int i = 0; i < trans.size(); i++)
    {
        if (trans[i] == "+" || trans[i] == "-" || trans[i] == "*" || trans[i] == "/")
        {
            float a, b;
            a = cal.top();
            cal.pop();
            b = cal.top();
            cal.pop();
            if (trans[i] == "+")
                cal.push(a + b);
            else if (trans[i] == "-")
                cal.push(b - a);
            else if (trans[i] == "*")
                cal.push(a * b);
            else
                cal.push(b / a);
        }
        else
        {
            cal.push(atof(trans[i].c_str()));
        }
    }
    return cal.top();
}
int main()
{
    int n;
    cin >> n;
    pri[‘+‘] = pri[‘-‘] = 0, pri[‘*‘] = pri[‘/‘] = 1, pri[‘(‘] = pri[‘)‘] = -1;
    while (n--)
    {
        cin >> str;
        Read();
        printf("%.2f\n",solve());
    }
    return 0;
}
				
时间: 2024-10-10 07:10:50

中缀表达式求值 C++ Stack的相关文章

中缀表达式求值问题

           中缀表达式求值问题 中缀表达式的求值问题是一个比较常见的问题之一,我们通常在编写程序时,直接写出表达式让编译器去处理,很少去关心编译器是怎么对表达式进行求值的,今天我们来一起了解一下其中具体的原理和过程. 表达式一般来说有三种:前缀表达式.中缀表达式.后缀表达式,其中后缀表达式又叫做逆波兰表达式.中缀表达式是最符合人们思维方式的一种表达式,顾名思义,就是操作符在操作数的中间.而前缀表达式和后缀表达式中操作符分别在操作数的前面和操作数的后面.举个例子: 3+2 这个是最简单的

中缀表达式求值总结

中缀表达式的题目困扰了我两三年,都没去写过..这两天看到2005年提高组的T3要用到所以心血来潮写了一下. 表达式求值借助基本结构应该不用说了是栈,不管手写还是STL都没有太大关系.而中缀表达式最难控制的地方是优先级,算上+-*/^()一共有四个优先级[+-,*/,, ^()](后面会提到一个三级的字符“负号”,这是预留空位). 下面对一个例子进行分析:2*3+4*6/3+17-4^2 那么处理的时候怎么控制优先级呢? 搜到‘+’之前,栈的情况是这样的: 操作数栈:2  3 操作符栈:* 然后搜

刁肥宅详解中缀表达式求值问题:C++实现顺序/链栈解决

1. 表达式的种类 如何将表达式翻译成能够正确求值的指令序列,是语言处理程序要解决的基本问题,作为栈的应用事例,下面介绍表达式的求值过程. 任何一个表达式都是由操作数(亦称运算对象).操作符(亦称运算符)和分界符组成的.通常,算术表达式有3种表示: ①中缀(infix)表示:<操作数><操作符><操作数>,如A+B. ②前缀(prefix)表示: <操作符><操作数><操作数>,如+AB. ③后缀(postfix)表示: <操作

中缀表达式求值

中缀表达式用于计算一个表达式,比如计算器 就是这样实现的 这儿是用栈的数据结构来实现的.首先输入一个字符串,表示一个表达式,然后用一个栈存储数字,另外一个栈存储符号 如果当前运算符优先级比栈顶元素优先级高,则入栈,若当前运算符优先级小于等于栈顶运算符优先级,则从数字栈中弹出两个元素,从符号栈中弹出一个符号,计算结果入栈(数字栈): 代码如下: #include<iostream> using namespace std; #include<cstring> #include<

【数据结构】栈的应用——中缀表达式求值(c++)

头文件: #pragma once #include <iostream> #include <assert.h> #include <string> using namespace std; template<class Type> class SeqStack { public: SeqStack(size_t sz = INIT_SZ); ~SeqStack(); public: bool empty()const; bool full()const;

中缀表达式求值模板

#include <bits/stdc++.h>using namespace std; /*判断符号间的优先关系函数*1表示>,0表示=,-1表示<*c1栈内的算符,c2栈外的算符*/int Judge(char c1,char c2){ int a1,a2; if('+'==c1||'-'==c1) a1 = 3; if('*'==c1||'/'==c1)a1 = 5; if('('==c1) a1 = 1; if(')'==c1) a1 = 7; if('#'==c1) a1

中缀表达式求值问题(栈的应用)

1 #include <iostream> 2 #include<stdlib.h> 3 4 using namespace std; 5 6 #define STACK_INIT_SIZE 100 7 #define STACKINCREASE 10 8 9 //为了简化函数,数据栈和符号栈用了一种结构体(虽然我知道可以用共用体解决问题,嫌烦), 10 //由此导致的后果是接下来所有的运算过程中不允许出现小数,而且由于是利用ASCII表来储存整数, 11 //所以要求运算数以及运

数据结构 栈的应用 --表达式求值

一: 中缀表达式求值  思想: 需要2个栈,运算对象栈OPND,运算符栈OPTR, 1:将栈OPND初始化为空,栈OPTR初始化为表达式的定界符# 2:扫描表达式,直到遇到结束符# 2.1:当前字符是运算对象,入栈OPND 2.2:当前字符是运算符且优先级比栈OPTR的栈顶运算符优先级高,入栈OPTR,处理下一个字符 2.3:当前字符是运算符且优先级比栈OPTR的栈顶运算符优先级低,则从栈OPND出栈2个运算对象,从栈OPTR出栈一个运算符进行运算,并将运算结果入栈OPND,处理当前字符 2.4

表达式求值及转换算法

后缀表达式求值算法 stack operands;  //运算数栈 while(没到表达式尾) {     scanf("一个运算对象op");     if(op is 运算数)         operands.push(op);     else if(op is 运算符)     {         operand_right = operands.pop();         operand_left = operands.pop();         result = op