练习5.1
题目:实现一个两层的stack类体系。其基类是个纯抽象类Stack,只提供最简单的接口:pop(),push(),size(),empty(),full(),peek(),print()。两个派生类则为LIFO_Stack和Peekback_Stack。
#include<iostream>
#include<string>
#include<vector>
#include<iterator>
using namespace std;
class Stack{
public:
virtual ~Stack(){}
//全部声明为纯虚函数,就不用再定义了
virtual bool pop(string& elem) = 0; //删除栈顶元素,并改变elem 的值
virtual bool push(const string&) = 0; //在栈顶增加元素
virtual bool peek(int index, string&) = 0; //查找某个地址的值是否存在
virtual int top() const = 0;
virtual int size() const = 0;
virtual bool empty() const = 0;
virtual bool full() const = 0;
virtual ostream& print(ostream &os) const = 0;
};
ostream& operator<<(ostream& os, const Stack &rhs)
{
return rhs.print(os);
}
class LIFO_Stack:public Stack{
public:
LIFO_Stack(int capacity = 0) :_top(0){ //考虑周全一点,capacity容量
if (capacity)
_stack.reserve(capacity);
}
int size() const { return _stack.size(); }
bool empty() const{ return !_top; }
bool full() const{ return size() >= _stack.max_size(); }
int top() const{ return _top; }
ostream& print(ostream&) const;
bool pop(string& elem);
bool push(const string& elem);
bool peek(int, string&) { return false; } //虽然这里peek函数没用,但基类里定义了此纯虚函数,这里必须申明定义
private:
int _top; //用来计算vector中的个数
vector<string> _stack;
};
bool LIFO_Stack::pop(string& elem)
{
if (empty()) return false;
elem = _stack.back();
_stack.pop_back();
--_top;
return true;
}
bool LIFO_Stack::push(const string& elem)
{
if (full()) return false;
_stack.push_back(elem);
++_top;
return true;
}
ostream& LIFO_Stack::print(ostream& os) const
{
vector<string>::const_reverse_iterator //反向迭代器,针对vector.rbegin()和vector.rend()
rit = _stack.rbegin(), //指向第一个元素前一个位置
rend = _stack.rend(); //指向最后一个元素
os << "\n\t";
while (rit != rend)
os << *rit++ << "\n\t";
os << endl;
return os;
}
class Peekback_Stack :public Stack{
public:
Peekback_Stack()
{
_top = 0;
}
int size() const { return _stack.size(); }
bool empty() const{ return !_top; }
bool full() const{ return size() >= _stack.max_size(); }
int top() const{ return _top; }
ostream& print(ostream&) const;
bool pop(string& elem);
bool push(const string& elem);
bool peek(int , string&);
private:
int _top;
vector<string> _stack;
};
bool Peekback_Stack::pop(string& elem)
{
if (empty()) return false;
elem = _stack.back();
_stack.pop_back();
--_top;
return true;
}
bool Peekback_Stack::push(const string& elem)
{
if (full()) return false;
_stack.push_back(elem);
++_top;
return true;
}
ostream& Peekback_Stack::print(ostream& os) const
{
vector<string>::const_reverse_iterator //反向迭代器,针对vector.rbegin()和vector.rend()
rit = _stack.rbegin(), //指向第一个元素前一个位置
rend = _stack.rend(); //指向最后一个元素
os << "\n\t";
while (rit != rend)
os << *rit++ << "\n\t";
os << endl;
return os;
}
bool Peekback_Stack::peek(int index, string& elem)
{
if (empty()) return false;
if (index < 0 || index >= size()) return false;
elem = _stack[index];
return true;
}
//下面以一个小程序演练。
//非成员函数peek接受一个“抽象类stack的reference”作为参数,并在函数内调用该stack对象的虚函数peek()
void peek(Stack& st, int index)
{
cout << endl;
string t;
if (st.peek(index, t))
cout << "peek: " << t;
else cout << "peek failed!";
cout << endl;
}
int main()
{
LIFO_Stack st;
string str;
while (cin >> str && !st.full())
st.push(str);
cout << '\n' << "About to call peek() with LIFO_Stack" << endl;
peek(st, st.top() - 1);
cout << st;
Peekback_Stack pst;
while (!st.empty())
{
string t;
if (st.pop(t))
pst.push(t);
}
cout << "About to call peek() with Peekback_Stack" << endl;
peek(pst, pst.top() - 1);
cout << pst;
system("pause");
}