stack的应用----一个简单的整数计算器

本例来自课本《c++语言程序设计(第4版)》第9章第9-9的案例
本例实现一个简单的整数计算器,能够进行加、减、乘、除和乘方运算。使用时算式采用后缀输入法,每个操作数、操作符之间都以空白符分隔。例如,若要计算“3+5”则输入“3 5 +”。乘方运算符用“^”表示。每次运算在前次结果基础上进行,若要将前次运算结果清除,可输入“c”。当输入“q”时程序结束

分析

本题实际上是要实现简单的表达式处理功能,可以用栈来处理表达式。对于比较复杂的表达式例如(1+5)/2-3,需要建立两个栈:操作数栈和操作符栈。但是本题的问题比较简单,每次输入的表达式只有一个操作符,因此没有操作优先级问题,也不需要操作符栈,可以只设一个操作数栈,

程序的主要思路

每当遇到操作数时,便入栈;遇到操作符时,便连续弹出两个操作数并执行运算,然后将运算结果压入栈顶。输入“c”时,清空操作数栈;输入“q”时,清空操作数栈并结束程序。

类设计的要点

建立一个计算器类,内嵌一个栈类操作对象作为操作数栈。成员函数应该包括:将操作数压入栈、连续弹出两个操作数、执行运算、对表达式的输入及计算过程的控制、清空操作数栈。

代码TIPS

tip1: 字符串输入 cin
对于cin而言,其输入结束条件为遇到enter、空格或tab键
例:

include<iostream>
include<string>
using namespace std;
int main(){
    string str;
    cin>>str;  //输入 10 20 30
    cout<<str<<endl;//输出为10
    return 0;
}

代码

代码包含三个文件“Calculator.h”、“Calculator.cbp”以及“main.cbp”,是使用codeblocks软件编写的c++语言的程序,对例9-9做了微调。

  1. 头文件 Calculator.h
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include<iostream>
#include<stack>
#include<cmath>
#include<sstream>
#include<string>
using namespace std;
class Calculator                  //计算器类
{
    public:
        void run();           //运行计算器程序
        void clear();         //清空操作数栈
    protected:

    private:
        stack<double> s;     //操作数栈
        void enter(double num); //将操作数num压入栈
        // 连续将两个操作数弹出栈,放在opnd1和opnd2中
        bool getTwoOperands(double &opnd1,double &opnd2);
        void compute(char op);// 执行由操作符op指定的运算
};

#endif // CALCULATOR_H

  1. 头文件实现文件 Calculator.cbp
#include "Calculator.h"

using namespace std;
void Calculator::enter(double num){  //将操作数num压入栈
    s.push(num);
}

//连续将两个操作数弹出栈,放在opnd1和opnd2中,
//如果栈中没有两个操作数,则返回false并输出相关信息
bool Calculator::getTwoOperands(double &opnd1,double &opnd2){
    if(s.empty()){ //检查栈是否为空
        cerr<<"Missing operand!"<<endl;
        return false;
    }
    opnd1 = s.top();      //将右操作数弹出栈
    s.pop();
    if(s.empty()){ //检查栈是否为空
        cerr<<"Missing operand!"<<endl;
        return false;
    }
    opnd2 = s.top();
    s.pop();
    return true;
}

void Calculator::compute(char op){            //执行运算
    double operand1,operand2;
    bool result = getTwoOperands(operand1,operand2);    //将两个操作数弹出栈

    if(result){                 //如果成功,执行运算并将运算结果压入栈
        switch(op){
        case '+':
            s.push(operand1+operand2);
            break;
        case '-':
            s.push(operand2-operand1);
            break;
        case '*':
            s.push(operand2*operand1);
            break;
        case '/':
            if(operand1==0){                  //检查除数是否为0
                cerr<<"Divided by 0!"<<endl;
                while(!s.empty())             //除数为0时清空栈
                    s.pop();
            }else{
                s.push(operand2/operand1);
            }
            break;
        case '^':
            s.push(pow(operand2,operand1));
            break;
        default:
            cerr<<"Unrecognized operator!"<<endl;
            break;
        }
        cout<<" = "<<s.top()<<endl;   //输出本次运算结果
    }else{         //操作数不够,清空栈
        while(!s.empty())
            s.pop();
    }
}

//工具函数,用于字符串转换为实数
inline double stringToDouble(const string &str){
    istringstream stream(str);   //字符串输入流
    double result;
    stream>>result;
    return result;
}

void Calculator::run(){ //读入并处理后缀表达式
    string str;
    while(cin>>str,str!="q"){  //cin 遇enter,space或tab键输入结束
        switch(str[0]){     //操作符
            case 'c':
                while(!s.empty())
                    s.pop();
                break;
            case '-':             // 遇“-”需判断是减号还是负号
                if(str.length()>1)   //如果字符串长度大于1,是负号
                {
                    enter(stringToDouble(str));
                }else
                {
                    compute(str[0]);
                }
                break;
            case '+':
            case '*':
            case '/':
            case '^':
                compute(str[0]);
                break;
            default:          //若读入的是操作数,转换为整型后压入栈
                enter(stringToDouble(str));
                break;
        }
    }
}

void Calculator::clear(){  //清空操作数栈
    while(!s.empty())
        s.pop();
}

  1. 主文件 main.cbp
#include <iostream>
#include"Calculator.h"
using namespace std;
/*
栈的应用----一个简单的整数计算器
本利实现一个简单的整数计算器,能够进行加、减、乘除运算。使用时算式采用
后缀输入法,每个操作数、运算符之间都以空白符分隔。例如,若要计算“3+5”
则输入“3 5 +”。乘法运算符用^表示。每次运算在前次结果基础上进行,若要将
前次运算结果清除,可输入‘c’,当输入“q”时,程序结束。
*/
int main()
{
    Calculator c;
    c.run();
    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值