1.栈的类模板:
#ifndef STACK_H
#define STACK_H
#include <cassert>
template <class T, int SIZE = 50>
class Stack {
private:
T list[SIZE];
int top;
public:
Stack();
void push(const T &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) { }
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;
}
#endif //STACK_H
2.用栈模板实现一个计算器:
实现一个简单的整数计算器,能够进行加、减、乘、除和乘方运算。使用时算式采用后缀输入法,每个操作数、操作符之间都以空白符分隔。例如,若要计算"3+5"则输入"3 5 +"。乘方运算符用"^"表示。每次运算在前次结果基础上进行,若要将前次运算结果清除,可键入"c"。当键入"q"时程序结束。
计算器类定义如下:
//Calculator.h
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include <iostream>
#include <sstream>
#include <cmath>
#include "Stack.h" // 包含栈类模板定义文件
using namespace std;
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(); //清空操作数栈
};
//工具函数,用于将字符串转换为实数
inline double stringToDouble(const string &str) {
istringstream stream(str); //字符串输入流
double result;
stream >> result;
return result;
}
void Calculator::enter(double num) { //将操作数num压入栈
s.push(num);
}
bool Calculator::getTwoOperands(double &opnd1, double &opnd2) {
if (s.isEmpty()) { //检查栈是否空
cerr << "Missing operand!" << endl;
return false;
}
opnd1 = s.pop(); //将右操作数弹出栈
if (s.isEmpty()) { //检查栈是否空
cerr << "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) { //检查除数是否为0
cerr << "Divided by 0!" << endl;
s.clear(); //除数为0时清空栈
}
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(); //操作数不够,清空栈
}
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();
}
#endif //CALCULATOR_H
3.测试函数:
#include <iostream>
#include "Calculator.h"
using namespace std;
int main()
{
Calculator c;
c.run();
return 0;
}
测试结果:
来自清华大学MOOC课件