编写了栈的类模板,实现了对不同类型对象基本的push、pop、清空、遍历、去长度、判断空满的功能,然后应用到了进制转换和括号匹配中去。
MyStack.h
#ifndef MYSTACK_H
#define MYSTACK_H
#include<iostream>
#include"MyStack.h"
#include<string>
//#include"Coordinate.h"//已成为通用的模板,所以不需要包含点类
using namespace std;
template<typename T>
class MyStack
{
public:
MyStack(int size);//分配内存空间,设置栈容量,栈顶
~MyStack();//回收栈空间
bool stackEmpty();
bool stackFull();
void clearStack();
int stackLength();
void push(T elem);
bool pop(T &elem);
T pop();
void stackTraverse(bool isFromBottom);
private:
int m_iSize;//容量
int m_iTop;//栈顶,栈中元素个数
T *m_pBuffer;//栈空间指针
};
template<typename T>
MyStack<T>::MyStack(int size)//分配内存空间,设置栈容量,栈顶
{
m_iSize = size;
m_pBuffer = new T[m_iSize];
m_iTop = 0;//栈顶为0
}
template<typename T>
MyStack<T>::~MyStack()//回收栈空间
{
delete []m_pBuffer;
}
template<typename T>
bool MyStack<T>::stackEmpty()
{
if(m_iTop == 0){
return true;
}
return false;
}
template<typename T>
bool MyStack<T>::stackFull()
{
if(m_iTop == m_iSize){
return true;
}
return false;
}
template<typename T>
void MyStack<T>::clearStack()
{
m_iTop = 0;//意味着栈内放的值都是无效的
}
template<typename T>
int MyStack<T>::stackLength()
{
return m_iTop;
}
template<typename T>
void MyStack<T>::push(T elem)
{
if(stackFull()){
throw string("已满!");//异常的两种处理,一种是try catch throw,一种是如pop那种返回bool值的方法
//cout << "已满!" << endl;
}else{//注意这里elem赋值是浅拷贝,调用到的是默认拷贝构造函数,是直接赋值,如果Coordinate类成员有指针类型的成员,那就需要自己定义一个拷贝函数并且用深拷贝
*(m_pBuffer+m_iTop) = elem;//m_pBuffer[m_iTop]=elem也可以
m_iTop ++;
}
}
template<typename T>
T MyStack<T>::pop()
{
if(stackEmpty()){
throw string("已空!");
}else{
m_iTop --;
return *(m_pBuffer+m_iTop);
}
}
template<typename T>
bool MyStack<T>::pop(T &elem)
{
if(stackEmpty()){
cout << "已空!" << endl;
return false;
}else{
m_iTop --;
elem = *(m_pBuffer+m_iTop);
return true;
}
}
template<typename T>
void MyStack<T>::stackTraverse(bool isFromBottom)
{
if(!isFromBottom){
for(int i = m_iTop-1;i >= 0;i--){
cout << m_pBuffer[i];//所以要求T类型对象都要重载运算符<<
//m_pBuffer[i].printCoordinate();
}
cout << endl;
}else{
for(int i = 0;i < m_iTop;i++){
cout << m_pBuffer[i];
//m_pBuffer[i].printCoordinate();
}
cout << endl;
}
}
#endif
没有MyStack.cpp,因为vs编译器不支持类模板声明和定义的分开,所以全都放在MyStack.h里
Coordinate.h
#ifndef COORDINATE_H
#define COORDINATE_H
#include<ostream>//因为用到了ostream类型
using namespace std;
class Coordinate
{
friend ostream& operator << (ostream &out,Coordinate &elem);//都用引用,节省空间
public:
Coordinate(int x = 0,int y = 0);
void printCoordinate();
private:
int m_iX;
int m_iY;
};//分号别忘
#endif
Coordinate.cpp
#include"Coordinate.h"
#include<iostream>
using namespace std;
Coordinate::Coordinate(int x,int y)
{
m_iX = x;
m_iY = y;
}
void Coordinate::printCoordinate()
{
cout << "(" << m_iX << "," << m_iY << ")" << endl;
}
demo.cpp
#include<iostream>
#include<stdlib.h>
#include<string>
#include"MyStack.h"
#include"Coordinate.h"
using namespace std;
/*
栈 类模板
可以让栈放任何数据类型的数据
*/
#define BINARY 2
#define OCTONARY 8
#define HEXADECIMAL 16
ostream& operator << (ostream &out,Coordinate &elem);//不再需要friend标识符
int main()
{
//栈模板验证
//MyStack<Coordinate> *pStack = new MyStack<Coordinate>(5);//选择不一样的类型的栈
//MyStack<char> *pStack1 = new MyStack<char>(2);
//try{
// pStack->push(Coordinate(1,2));//底
// pStack->push(Coordinate(2,2));
// pStack->push(Coordinate(3,2));
// pStack->push(Coordinate(4,2));
// pStack->push(Coordinate(5,2));//顶
// pStack->stackTraverse(0);
// Coordinate elem = pStack->pop();
// //cout << elem << endl;
// elem.printCoordinate();
// pStack->stackTraverse(0);
// pStack->push(Coordinate(6,2));
// cout << pStack->stackLength() << endl;
// pStack->clearStack();
// pStack->pop(elem);
// if(pStack->stackEmpty()){
// cout << "空!" << endl;
// }
// if(pStack->stackFull()){
// cout << "满!" << endl;
// }
// pStack1->push('d');
// pStack1->push('s');
// pStack1->stackTraverse(0);
//}
//catch(string &str){
// cout << str << endl;
//}
//cout << "test" << endl;//catch执行完后也会继续执行
//delete pStack;
//pStack = NULL;
//应用:实现十进制到任意进制转换
//MyStack<int> *pStack = new MyStack<int>(30);
//char num[] = "0123456789abcdef";//考虑到16进制打印显示abcdef的问题
//int N = 1354;
//int M = 0;
//int d = HEXADECIMAL;
//while(N != 0){
// M = N%d;
// pStack->push(M);
// N = N / d;
//}
////pStack->stackTraverse(0);
////int length = pStack->stackLength();
////for(int i = 0;i != length;i++){
//// cout << num[pStack->pop()];//pop之后,栈的长度会改变
////}
////cout << endl;
//while(!(pStack->stackEmpty())){
// cout << num[pStack->pop()];
//}
//cout << endl;
//delete pStack;
//应用:括号匹配
MyStack<char> *pStack = new MyStack<char>(30);//纪录扫描到的字符
MyStack<char> *pNeedStack = new MyStack<char>(30);//记录栈顶急需的字符
char str[] = "[]]";
char currentNeed = 0;//表示当前所需要的字符,赋一个不可见的字符初值
for(int i = 0;i < strlen(str);i ++){
if(str[i] != currentNeed){
pStack->push(str[i]);
//pNeedStack->push(currentNeed);
//if(str[i] == '['){
// currentNeed = ']';
//}else if(str[i] == '{'){
// currentNeed = '}';
//}else if(str[i] == '('){
// currentNeed = ')';
//}else{
// break;
//}
//用switch比较好
switch(str[i]){
case '[':
if(currentNeed != 0){//之所以写到这里而不写在switch外面是为了以后扩展方便,因为不是每种情况都要进行这个判断
pNeedStack->push(currentNeed);
}
currentNeed = ']';
break;
case '{':
if(currentNeed != 0){
pNeedStack->push(currentNeed);
}
currentNeed = '}';
break;
case '(':
if(currentNeed != 0){
pNeedStack->push(currentNeed);
}
currentNeed = ')';
break;
default:
cout << "不匹配" << endl;
delete pStack;
delete pNeedStack;
system("pause");
return 0;
}
}else{
if(!pNeedStack->pop(currentNeed)){
currentNeed = 0;
}
pStack->pop();
}
}
if(pStack->stackEmpty()){
cout << "全部匹配" << endl;
}else{
cout << "不匹配" << endl;
}
delete pStack;
delete pNeedStack;
system("pause");
return 0;
}
ostream& operator << (ostream &out,Coordinate &elem)
{
out << "(" << elem.m_iX << "," << elem.m_iY << ")" << endl;
return out;
}