C++标准模版库中的栈模版类提供了一些方法可以对栈进行简单的操作,其中提供的方法如下:
bool empty( ) const;
查看栈是否为空,如果为空返回true,否则返回false。
void pop( );
弹出位于栈顶的对象,栈中的对象个数减一。不返回任何值。
void push(const Type& _Val);
将Type类型的值_Val压进栈,栈中的对象个数加一。不返回任何值。
size_type size( ) const;
返回栈的大小,即栈中对象的个数。其中size_type是一个unsigned size类型。
value_type& top( );
const value_type& top( ) const;
返回位于栈顶的对象,不修改栈中的对象。
大家可以看到,标准库中栈类提供的方法很有限,而且不能限定栈的大小,而且在对空栈进行pop操作时因没有采取防范措施会导致应用程序崩溃,这是很不安全的,因此在扩展栈模版类时我会在构造函数中指定栈中能够盛放最大对象个数。通过参考java类库,为方便对栈的操作,可以为栈添加如RemoveAll()、ElementAt()等方法。重新定义的方法如下:
bool Push(T i);
如果栈未满,即栈中的对象个数小于栈的大小,则将对象i压进栈,并返回true;如果栈已满,不执行任何操作,返回false。其中T为i的数据类型,下同。
T Pop();
如果栈为非空,弹出位于栈顶的对象,栈中的对象个数减一。返回弹出的对象。
T Peek();
如果栈为非空,返回位于栈顶的对象,不修改栈中的对象。其功能和原来stack的top()方法相同。
void RemoveAll();
弹出栈中所有的对象,即将栈清空。
bool IsEmpty();
查看栈是否为空,如果为空返回true,否则返回false。其功能和原来stack的empty()方法相同。
T ElementAt(int i);
返回位于栈中第i个对象,此对象的位置从栈底算起。
unsigned int Size();
返回栈的大小,即栈中对象的个数。
bool SetMaxSize(unsigned int mSize);
如果当前栈中对象的个数设置栈的大小,即设置栈能够盛放的最大对象的个数,并返回true。否则返回false。
基于以上提供的栈方法,我使用了断言(assert)来判断当前操作的合法性,如不能对空栈执行pop操作,如果进行pop操作则产生一个异常(是abnormal,它与exception不同,abnormal的产生是由assert后的布尔表达式为假产生的,并不是运行时的错误)。扩展后的栈模版类的代码如下:
//*********Stack.h***********
//*******Code: hifrog********
#include<stack>
#include<assert.h>
using namespace std;
template<typename T>
class Stack
{
private:
stack<T> s;
unsigned int MaxSize;
public:
Stack(unsigned int mSize)
{
MaxSize=mSize;
}
bool Push(T i)
{
if(Size()<MaxSize)
{
s.push(i);
return true;
}
return false;
}
T Pop()
{
T tmp=0;
assert(!s.empty());
tmp=s.top();
s.pop();
return tmp;
}
T Peek()
{
assert(!s.empty());
return s.top();
}
void RemoveAll()
{
while(!s.empty())
s.pop();
}
bool IsEmpty()
{
return s.empty();
}
T ElementAt(int i)
{
assert(i>0&&i<=Size());
int tmp=(int)s.size();
T value=0;
stack<T> tmpS; //这里使用了一个临时栈保存从s栈中弹出的元素
//用来获得位置为i的元素的值
for(int k=tmp;k>i;k--)
{
tmpS.push(s.top());
assert(!s.empty());
s.pop();
}
assert(!s.empty());
value=s.top();
for(int j=tmp;j>i;j--)
//向s栈回填弹出的元素
{
s.push(tmpS.top());
assert(!s.empty());
tmpS.pop();
}
return value;
}
unsigned int Size()
{
return (unsigned int)s.size();
}
bool SetMaxSize(unsigned int mSize)
{
if(mSize>Size())
{
MaxSize=mSize;
return true;
}
return false;
}
};
而且写了一个测试程序:
#include "Stack.h"
//#include<string>
#include<iostream>
using namespace std;
int main()
{
double db_array[]=
{
1.1,2.2,3.3,4.4,5.5
};
Stack<double> db_stack(10);
int i=0;
while(i<5)
{
db_stack.Push(db_array[i]);
i++;
}
cout<<db_stack.Size()<<endl;
cout<<db_stack.ElementAt(2)<<endl;
while(!db_stack.IsEmpty())
{
cout<<db_stack.Pop()<<endl;
}
//db_stack.Pop();
return 0;
}
运行结果如下:
5
2.2
5.5
4.4
3.3
2.2
1.1