在栈的实现 - C++中,简要介绍了栈的相关特性,及其C++的实现。在栈的应用 - 波兰式与逆波兰式中,借助于栈,实现了中缀表达式到前缀表达式和后缀表达式的转换。
正如已经提到的,因为此前在实现栈的时候,栈的元素类型elementType是通过typedef来指定的,这样虽然也可以根据需要实例化不同类型的栈,但是在一个应用中,只能指定一种元素类型,其使用也就受到了一定的限制。也正是由于这个限制,我没有同时给出波兰式和逆波兰式的计算,因为转换过程中,栈的元素类型是char,而在计算的过程中,栈的元素类型是int。当然,我们可以再定义一个类,但是这样真的太麻烦,而且很不优雅,在C++中有一个很好的工具——模板,它可以非常完美地解决我的问题,下面的代码中,对栈的实现做了略微的修改,并且将波兰式与逆波兰式的计算也补齐了。
波兰式与逆波兰式的计算规则在栈的应用 - 波兰式与逆波兰式中已经说明了,在此不做赘述,不过值得注意的点还是要再强调一下,给自己也提个醒吧。在计算时,操作数的顺序要格外注意,否则遇到减法或除法就可能会产生错误的结果。
- 计算前缀表达式(波兰式)时,从右至左扫描表达式 ,出栈时,先弹出的为操作数1(op1),后弹出的为操作数2(op2)
- 计算后缀表达式(逆波兰式)时,从左至右扫描表达式,出栈时,先弹出的为操作数2(op2),后弹出的为操作数1(op1)
- 对于除法,要检测除数(op2)是否为0
实现代码
MyStack.h
#ifndef _MYSTACK_H_
#define _MYSTACK_H_
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <iomanip>
using namespace std;
#define INISIZE 2
#define INIINCREMENT 2
#define DYNAMIC
//typedef char elementType;
template <class elementType>
class MyStack {
public:
int top;
int size;
int increment;
elementType * data;
MyStack(int size = INISIZE, int increment = INIINCREMENT);
~MyStack();
bool pop(elementType & e);
bool push(elementType e);
bool isEmpty();
bool isFull();
bool getTopElement(elementType & e);
void printStack(); //打印栈中所有的元素,主要用于调试
};
template <class elementType>
MyStack<elementType>::MyStack(int size, int increment)
{
top = -1;
this->size = size;
this->increment = increment;
data = (elementType *)malloc(sizeof(elementType) * this->size);
}
template <class elementType>
MyStack<elementType>::~MyStack()
{
if (data) {
free(data);
}
}
template <class elementType>
bool MyStack<elementType>::pop(elementType & e)
{
if (isEmpty()) {
e = -1;
return false;
} else {
e = data[top];
top --;
return true;
}
}
template <class elementType>
bool MyStack<elementType>::push(elementType e)
{
if (isFull()) {
#ifdef DYNAMIC
size = size + increment;
data = (elementType *)realloc(data, sizeof(elementType) * this->size);
if (data == NULL) {
return false;
}
top ++;
data[top] = e;
return true;
#else
return false;
#endif
} else {
top ++;
data[top] = e;
return true;
}
}
template <class elementType>
bool MyStack<elementType>