基本内容
实验内容:编写程序,模拟简单运算器的工作:输入一个算式,遇等号“=”说明输入结束,输出结果。假设计算器只能计算加减乘除运算,运算数和结果都是整数。要求完成输入后缀表达式(空格隔开以区分不同数字),计算后缀表达式的值。
实现程序
- 顺序栈模板类的实现
#ifndef __SQ_STACK_H__
#define __SQ_STACK_H__
#include <cstring>
#include <iostream>
using namespace std;
#define DEFAULT_SIZE 100
// 顺序栈模板类
template<class ElemType>
class SqStack
{
protected:
// 顺序栈的数据成员:
int top; // 栈顶指针
int maxSize; // 栈的最大容量
ElemType* data; // 元素存储空间
public:
// 顺序栈的方法声明及重载编译系统默认方法声明:
SqStack(int size = DEFAULT_SIZE); // 构造函数
virtual ~SqStack(); // 析构函数
int getLength() const; // 求栈的长度
bool isEmpty() const; // 判断栈是否为空
void clear(); // 将栈清空
void traverse(void (*Visit)(const ElemType&)) const; // 遍历栈
int push(const ElemType e); // 入栈
int getTop(ElemType& e) const; // 取栈顶元素
int pop(ElemType& e); // 出栈
SqStack(const SqStack<ElemType>& s); // 复制构造函数
SqStack<ElemType>& operator =(const SqStack<ElemType>& s); // 赋值语句重载
};
template<class ElemType>
SqStack<ElemType>::SqStack(int size)
{
top = -1;
maxSize = size;
data = new ElemType[maxSize];
}
template<class ElemType>
SqStack<ElemType>::~SqStack()
{
delete[] data;
}
template<class ElemType>
int SqStack<ElemType>::getLength() const
{
return top + 1;
}
template<class ElemType>
bool SqStack<ElemType>::isEmpty() const
{
return top == -1;
}
template<class ElemType>
void SqStack<ElemType>::clear()
{
top = -1;
}
template<class ElemType>
void SqStack<ElemType>::traverse(void (*Visit)(const ElemType&)) const
{
int cur = top;
while (cur >= 0) {
Visit(cur--);
}
}
template<class ElemType>
int SqStack<ElemType>::push(const ElemType e)
{
// 栈满则入栈失败,否则将新元素压入栈顶
if (this->getLength() == maxSize) {
return 0;
}
else {
data[++top] = e;
return 1;
}
}
template<class ElemType>
int SqStack<ElemType>::getTop(ElemType& e) const
{
// 栈空则失败,否则修改e为栈顶元素
if (this->isEmpty()) {
return 0;
}
else {
e = data[top];
return 1;
}
}
template<class ElemType>
int SqStack<ElemType>::pop(ElemType& e)
{
// 若栈空则出栈失败,否则将e修改为栈顶元素,并弹出栈顶元素
if (this->isEmpty()) {
return 0;
}
else {
e = data[top];
top--;
return 1;
}
}
template<class ElemType>
SqStack<ElemType>::SqStack(const SqStack<ElemType>& s)
{
top = s.top;
maxSize = s.maxSize;
data = new ElemType[maxSize];
for (int i = 0; i <= top; ++i) {
data[i] = s.data[i];
}
}
template<class ElemType>
SqStack<ElemType>& SqStack<ElemType>::operator=(const SqStack<ElemType>& s)
{
top = s.top;
maxSize = s.maxSize;
delete[] data;
data = new ElemType[maxSize];
for (int i = 0; i <= top; ++i) {
data[i] = s.data[i];
}
return *this;
}
#endif
这是定长型的顺序栈,栈顶指针指向栈顶元素,top的值即为栈顶元素的下标值。
- 计算后缀表达式的函数
输入一个后缀表达式字符串之后,由左向右依次读取字符
1.读取到数字就直接入栈
2.当读入运算符就直接将栈中前两个数弹出,其中先弹出的为右操作数,后弹出的为左操作数,计算之后将结果压入栈中。
3.直至读取完毕,栈中剩余的数据的就是结果
一定是最终栈中只有一个数据,若是有多个数据则说明输入的后缀表达式有误。
void cal() {//计算后缀表达式的值
SqStack<int>Val;
char s[DEFAULT_SIZE];
int re;
cout << "请输入要计算的后缀表达式(空格隔开):";
again:
while (1) {
int len = 0;
char c;
while ((c = getchar()) != EOF && len < DEFAULT_SIZE) {//读入整行字符串
if ('\n' == c) { break; }
s[len] = c;
len++;
}
if (s[len-1] != '=') {
cout << "结尾不是等号,请重新输入:" << endl; goto again;
}
for (int i = 0; i < len-1; i++) {
char c = s[i];
int val, val1, val2, val3;
if (isdigit(c)) {
val = c - '0';
while (i + 1 < len-1 && isdigit(s[i + 1])) {
++i;
val = val * 10 + s[i] - '0';
}
Val.push(val);
}
else if (c == ' ') {}
else if (c == '+') {
Val.pop(val1); Val.pop(val2);
val3 = val2 + val1;
Val.push(val3);
}
else if (c == '-') {
Val.pop(val1); Val.pop(val2);
val3 = val2 - val1;
Val.push(val3);
}
else if (c == '*') {
Val.pop(val1); Val.pop(val2);
val3 = val2 * val1;
Val.push(val3);
}
else if (c == '/') {
Val.pop(val1); Val.pop(val2);
val3 = val2 / val1;
Val.push(val3);
}
else {
cout << "含有非法字符,请重新输入:";
Val.clear(); goto again;
}
}
break;
}
Val.pop(re);
cout << "计算结果:" << re << endl;
}
首先定义一个数字栈来存放表达式中的数字以及每一步计算得到的数字,为了区别每一个操作数,表达式必须用空格隔开,这就需要用getchar()来读入整个表达式了。输入表达式后就是分析了,数字压入数字栈,空格不作处理,其他的遇到运算符时则弹出数字栈栈顶的两个元素,用次顶元素运算栈顶元素,然后将结果压入数字栈,分析完表达式后数字栈栈顶元素就是表达式的结果。
程序结果