2014-03-18 05:17
题目:设计一个栈,这个栈实际上由一列子栈组成。每当一个子栈的大小达到n,就新产生下一个子栈。整个栈群对外看起来就像普通栈一样,支持取顶top()、压入push()、弹出pop()操作。另外再实现一个弹出特定子栈popAt()的操作。
解法:用stack构成的数组,可以实现快速的随机访问。用stack构成的链表实现,可以防止在中间的一些子栈进行pop操作造成的空隙,但顺序访问的效率要低一些。得根据执行这些操作的偏好和频率来定。
代码:
1 // 3.3 Implement a stack with multiple sub-stacks. If one substack exceeds some threshold, allocate a new stack. 2 #include <cstdio> 3 #include <stack> 4 #include <vector> 5 using namespace std; 6 7 template <class T> 8 class StackSet { 9 public: 10 StackSet(size_t capacity = 1): mcapacity(capacity), msize(0) {} 11 12 void push(T val) { 13 if (mdata.empty() || mdata[mdata.size() - 1].size() == mcapacity) { 14 mdata.push_back(stack<T>()); 15 } 16 mdata[mdata.size() - 1].push(val); 17 ++msize; 18 } 19 20 void pop() { 21 if (mdata.empty()) { 22 return; 23 } 24 25 mdata[mdata.size() - 1].pop(); 26 --msize; 27 while (!mdata.empty() && mdata[mdata.size() - 1].empty()) { 28 mdata.pop_back(); 29 } 30 } 31 32 void popAt(size_t idx) { 33 if (mdata.empty()) { 34 return; 35 } 36 37 if (idx < 0 || idx > mdata.size() - 1) { 38 pop(); 39 return; 40 } 41 42 if (mdata[idx].empty()) { 43 return; 44 } 45 46 mdata[idx].pop(); 47 --msize; 48 } 49 50 T top() { 51 return mdata[mdata.size() - 1].top(); 52 } 53 54 size_t size() { 55 return msize; 56 } 57 private: 58 vector<stack<T> > mdata; 59 size_t mcapacity; 60 size_t msize; 61 }; 62 63 int main() 64 { 65 char str[100]; 66 int val; 67 68 scanf("%d", &val); 69 StackSet<int> ss(val); 70 while (scanf("%s", str) == 1) { 71 if (strcmp(str, "end") == 0) { 72 break; 73 } else if (strcmp(str, "push") == 0) { 74 scanf("%d", &val); 75 ss.push(val); 76 } else if (strcmp(str, "pop") == 0) { 77 ss.pop(); 78 } else if (strcmp(str, "top") == 0) { 79 printf("top=%d ", ss.top()); 80 } else if (strcmp(str, "size") == 0) { 81 printf("size=%u ", ss.size()); 82 } else if (strcmp(str, "popat") == 0) { 83 scanf("%d", &val); 84 ss.popAt(val); 85 } 86 } 87 88 return 0; 89 }