首页 > 其他 > 详细

DS堆栈--表达式计算

时间:2020-01-10 21:17:54      阅读:102      评论:0      收藏:0      [点我收藏+]

题目描述

计算一个表达式的运算结果

使用C++自带stack堆栈对象来实现

参考课本的伪代码,把伪代码改造成可运行的代码

课本伪代码请下载本附件:表达式伪c代码

例如

1. Push (OPTR, ‘#‘);表示把字符#压入堆栈OPTR中,转换成c++代码就是OPTR.push(‘#‘);

2. Pop(OPND, a); 表示弹出栈OPND的栈顶元素,并把栈顶元素放入变量a中。因此改成c++代码是两个操作:

    a = OPND.top();   OPND.pop();

3. a = GetTop(OPND)表示获取栈OPND的栈顶元素,转成c++代码就是: a = OPND.top(); 

技术分享图片     

技术分享图片

 

 

 

技术分享图片

 

输入

第一个输入t,表示有t个实例

第二行起,每行输入一个表达式,每个表达式末尾带#表示结束

输入t行

 

输出

每行输出一个表达式的计算结果,计算结果用浮点数(含4位小数)的格式表示

用cout控制浮点数输出的小数位数,需要增加一个库文件,并使用fixed和setprecision函数,代码如下:

#include <iostream>
#include<iomanip>
using namespace std;

int main()

{ double temp = 12.34

cout<<fixed<<setprecision(4)<<temp<<endl;

}

输出结果为12.3400

 

样例输入

2 1+2*3-4/5# (66+(((11+22)*2-33)/3+6)*2)-45.6789#

样例输出

6.2000 54.3211

提示

#include<iostream>
#include<stack>
#include<string>
#include<sstream>
#include<iomanip>
using namespace std;
 
#define ok 0
#define error -1
#define opsetsize 7//运算符集合长度,目前只有7个运算符
 
char Prior[7][7]=
{
    ///运算符间的优先关系,分别是+ - * / ( ) #
    ///按行看+ - * / ( ) #
    >,>,<,<,<,>,>,
    >,>,<,<,<,>,>,
    >,>,>,>,<,>,>,
    >,>,>,>,<,>,>,
    <,<,<,<,<,=, ,
    >,>,>,>, ,>,>,
    <,<,<,<,<, , 
};
 
double Operate(double a,char theta,double b)
{
    if(theta==+)
        return a+b;
    else if(theta==-)
        return a-b;
    else if(theta==*)
        return a*b;
    else if(theta==/)
        return a/b;
    return error;
}
char opset[opsetsize]={+, -, *, /, (, ),#};///运算符集合
int in(char Test,char *p)///1是运算符,0不是运算符
{
    ///判断字符Test是否是运算符
    for(int j=0;j<opsetsize;j++)
    {
        if(Test==p[j])
            return 1;
    }
    return 0;
}
char precede(char Aop,char Bop)
{
    ///获取两个运算符之间的优先级,Aop是栈顶,Bop是下一个运算符
    int i;
    for(i=0;i<opsetsize;i++)
        if(opset[i]==Aop)
            break;
    int j;
    for(j=0;j<opsetsize;j++)
        if(opset[j]== Bop)
            break;
    return Prior[i][j];
}
 
double EvaluateExpression(string Myexp)
{
    stack<char>Optr;///运算符栈
    stack<double>Opnd;///操作数栈
    string Tempdata;
    double data;
    char theta;
    char c;
    int i=0;///用于控制字符串的位置移动
    stringstream ss;
    Optr.push(#);///先压入一个#号
    c= Myexp[0];
    while(c!=#||Optr.top()!=#)
    {
        if(in(c, opset)==0)
        {
            ///判断读入的字符是不是操作数,是则进入
            Tempdata+=c;
            c=Myexp[++i];///读取下一个字符
            if(in(c, opset)!=0)
            {
                ///如果c是运算符,表明前面读入了一个完整的操作数
                ss.clear();
                if(Tempdata.size()!=0)
                {
                    ss<<Tempdata;
                    ss>>data;
                    Opnd.push(data);
                    Tempdata.clear();
                }
            }
        }
        else
        {
            ///是运算符,开始计算
            switch(precede(Optr.top(),c))
            {
                case<:///栈顶的优先级低,即Op1<Op2,不进行计算,压入新的运算符
                    Optr.push(c);
                    c= Myexp[++i];
                    break;
                case=:///脱括号和脱#号
                    Optr.pop();
                    c=Myexp[++i];
                    break;
                case>:///退栈并将计算结果入栈
                    double b=Opnd.top();///第一个弹出右操作数
                    Opnd.pop();
                    double a=Opnd.top();///第二个弹出左操作数
                    Opnd.pop();
                    theta=Optr.top();
                    Optr.pop();
                    Opnd.push(Operate(a,theta,b));
                    break;
            }
        }
    }
    return Opnd.top();
}
int main()
{
    string exp;
    int T;
    cin>>T;
    while(T--)
    {
        cin>>exp;
        exp+="#";
        double result=EvaluateExpression(exp);
        cout<<fixed<<setprecision(4)<<result<<endl;
    }
    return 0;
}

DS堆栈--表达式计算

原文:https://www.cnblogs.com/SZU-DS-wys/p/12177984.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!