鱼C论坛

 找回密码
 立即注册
查看: 3286|回复: 8

[技术交流] 利用栈的特性实现的简单逆波兰运算(C++)

[复制链接]
发表于 2016-4-9 19:29:52 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
/*"stacklist.h"——一个用C++类模块的方式编写的顺序存储式栈表的头文件,借用栈先进后出(FILO)的结构特性,实现小型逆波兰运算的功能*/
#include<iostream>
using namespace std;

const int maxsize=20;   //栈最大空间
template<class Selemtype>
class Stacklist
{public:
        Stacklist();
        void Push(Selemtype x);
        Selemtype Pop();
        int Empty();
private:
        Selemtype data[maxsize];
        int top;
};
template<class Selemtype>
Stacklist<Selemtype>::Stacklist()    //栈的初始化,top=-1,栈顶位于栈底下边
{
        top=-1;
}
template<class Selemtype>
void Stacklist<Selemtype>::Push(Selemtype x)  //压栈,将数据推入栈中
{
        if(maxsize-1==top)throw"Error";
        data[++top]=x;
}
template<class Selemtype>
Selemtype Stacklist<Selemtype>::Pop()    //弹栈,将栈顶数据弹出栈
{
        if(-1==top)throw"Error";
        return data[top--];
}
template<class Selemtype>
int Stacklist<Selemtype>::Empty()    //判断是否为空栈
{
        if(-1==top)return 1;
        else return 0;
}

/*"stacklist.cpp"——一个借用栈将中缀表达式转换为后缀表达式,运用逆波兰实现表达式运算的源文件*/
#include<iostream>
#include"stacklist.h"
using namespace std;

Stacklist<double>data;   //创建存储double数据的栈表,用于暂时存储即将进行运算的值
Stacklist<char>symbol;   //创建存储char数据的栈表,用于暂时存储运算符号
int main()
{
        char c,s,str[maxsize];
        int i=0;
        void calculator(char);   //传入运算符进行相应运算的函数
        cout<<"请输入中缀运算表达式,并以#作为结束字符:"<<endl;
        cin>>c;
        while(1)
        {
                while(c>='0'&&c<='9')  //由于输入都为char型,循环连续的数字输入,确保获取多位数值
                {
                        str[i++]=c;     //将一个一个输入的char型数字暂时存入一个char数组中
                        cin>>c;
                        if(c<'0'||c>'9')
                        {
                                str='\0';  //在数值输入结束时,结尾存入‘\0',代表当前数字字符串输入结束
                                data.Push(atof(str));   //asof函数用于将保存的数字字符转换为double型数值
                                i=0;     //char数组指标归零
                        }
                }
                if(')'==c)  //当遇到')'时,由于括号内优先运算,则将先前入栈的运算符依次弹栈并同时从数据栈弹出两个数据用于计算(到弹出'('为止)
                {
                        s=symbol.Pop();
                        while('('!=s)
                        {
                                calculator(s);
                                s=symbol.Pop();
                        }
                }
                else if('*'==c||'/'==c||'('==c)     //由于'*','/','('的优先级较高,则先暂时压入栈中
                {
                        symbol.Push(c);
                }
                else if('+'==c||'-'==c)     //由于'+','-'优先级较低,则将栈中高级或等级的运算符弹栈以优先运算(直到遇上'('或栈空为止),最后还应将该运算符暂时压栈
                {
                        if(symbol.Empty())symbol.Push(c);   //如栈空则直接压栈
                        else
                        {
                                while(!symbol.Empty()&&'('!=s)
                                {
                                        s=symbol.Pop();
                                if('('==s)symbol.Push(s);    //当弹出的是'(',则重新压回栈中
                                        else calculator(s);
                                }
                                symbol.Push(c);
                        }
                }
                else if(c=='#')break;    //以'#'作为输入结束符
                else cout<<"输入字符格式出错"<<endl;
                cin>>c;
        }
        while(!symbol.Empty())     //最后将运算符栈中的所以运算符弹栈并进行运算
        {
                s=symbol.Pop();
                calculator(s);
        }
        cout<<"最后的运算结果为: "<<data.Pop()<<endl;     //从数据栈中弹出最终运算结果
        return 0;
}

void calculator(char c)     //进行相应的符号运算
{
        double d1,d2;
        d1=data.Pop();
        d2=data.Pop();
        switch(c)
        {
        case'+':
                data.Push(d2+d1);break;
        case'-':
                data.Push(d2-d1);break;
        case'*':
                data.Push(d2*d1);break;
        case'/':
                if(0==d1)cout<<"除数不能为0"<<endl;
                else data.Push(d2/d1);
                break;
        default:cout<<"运算符输出错误"<<endl;
        }
}

评分

参与人数 1荣誉 +3 鱼币 +5 收起 理由
~风介~ + 3 + 5 感谢楼主无私奉献!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-4-13 16:40:06 | 显示全部楼层
嗯嗯
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-4-13 22:25:58 | 显示全部楼层
学习学习  路过
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-5-16 00:50:20 | 显示全部楼层
XIE XIE L OU ZHU
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-5-16 20:18:13 | 显示全部楼层
感谢分享
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-5-22 15:13:11 | 显示全部楼层
看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-5-23 13:59:56 | 显示全部楼层
利用栈的特性实现的简单逆波兰运算
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-5-25 13:17:55 | 显示全部楼层
vbbnm
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-5-26 14:46:21 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 05:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表