参考《C++语言程序设计(第4版)第9章 群体类和群体数据的组织 例9-8 栈类 例9-9 栈的应用——一个简单的整数计数器》
Stack.h
#pragma once
#include <cassert>
//模板的定义,SIZE为栈的大小
template<class T,int SIZE=50>
class Stack {
private:
T list[SIZE]; //数组,用于存放栈的元素
int top; //栈顶位置(数组下标)
public:
Stack(); //构造函数,初始化栈
void push(const T& item); //将元素item压入栈
T pop(); //将栈顶元素弹出栈
void clear(); //将栈清空
const T& peek() const; //访问栈顶元素
bool isEmpty() const; //测试是否栈空
bool isFull() const; //测试是否栈满
};
//模板的实现
template<class T,int SIZE>
Stack<T,SIZE>::Stack():top(-1){ } //构造函数,栈顶初始化为-1
template<class T, int SIZE>
void Stack<T, SIZE>::push(const T& item) {
assert(!isFull());
list[++top] = item;
}
template<class T, int SIZE>
T Stack<T, SIZE>::pop() {
assert(!isEmpty());
return list[top--];
}
template<class T, int SIZE>
const T& Stack<T, SIZE>::peek() const {
assert(!isEmpty());
return list[top];
}
template<class T, int SIZE>
bool Stack<T, SIZE>::isEmpty() const {
return top == -1;
}
template<class T, int SIZE>
bool Stack<T, SIZE>::isFull() const {
return top == SIZE - 1;
}
template<class T, int SIZE>
void Stack<T, SIZE>::clear() {
top = -1;
}
Calculator.h
#pragma once
#include "Stack.h"
class Calculator {
private:
Stack<double>s; //操作数栈
void enter(double num); //将操作数num压入栈
//连续将两个操作数弹出栈,放在opnd1和opnd2中
bool getTwoOperands(double& opnd1, double& opnd2);
void compute(char op); //执行由操作符op指定的运算
public:
void run(); //运行计算器程序
void clear(); //清空操作数栈
};
Calculator.cpp
#include "Calculator.h"
#include <iostream>
#include <sstream>
#include <cmath>
using namespace std;
void Calculator::enter(double num) {
s.push(num);
}
bool Calculator::getTwoOperands(double& opnd1, double& opnd2) {
if (s.isEmpty()) {
cout << "Missing operand!" << endl;
return false;
}
opnd1 = s.pop(); //将右操作数弹出栈
if (s.isEmpty()) {
cout << "Missing operand!" << endl;
return false;
}
opnd2 = s.pop(); //将左操作数弹出栈
return true;
}
void Calculator::compute(char op) {
double operand1, operand2;
bool result = getTwoOperands(operand1, operand2);
if (result) {
switch (op)
{
case '+':
s.push(operand2 + operand1);
break;
case '-':
s.push(operand2 - operand1);
break;
case '*':
s.push(operand2 * operand1);
break;
case '/':
if (operand1 == 0) {
cout << "Divided by 0!" << endl;
s.clear();
}
else
s.push(operand2 / operand1);
break;
case '^':
s.push(pow(operand2, operand1));
break;
default:
cerr << "Unrecognized operator!" << endl;
break;
}
cout << "=" << s.peek() << " ";
}
else
s.clear();
}
//工具函数,用于将字符串转换为实数
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") {
switch (str[0])
{
case 'c':
s.clear();
break;
case '-':
if (str.size() > 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() {
s.clear();
}