STL除了给我们提供了一些容器(container)以外,还给我们提供了几个容器适配器(container adapters),stack便是其中之一
看过STL源码的人都知道,stack其实是内部封装了 deque给我们使用,所有的操作,在内部都是基于deque的实现,
在<stack> 中,class stack的定义:
unamespace std{
template <class T, class container = deque<T> >
class stack;
}
所以我们也可以自己定义它内部的容器(但是你通常不会这样做如果你没有看过源代码):
std::stack<int, std::vector<int> > st;
stack的接口很简单,就那么几个:
push();
pop();//不返回最后一个值
top();//返回最后一个值
empty();
size();
看我从网上找的一个竞赛题:
Description
Input
Output
Sample Input
VISIT http://acm.ashland.edu/ VISIT http://acm.baylor.edu/acmicpc/ BACK BACK BACK FORWARD VISIT http://www.ibm.com/ BACK BACK FORWARD FORWARD FORWARD QUIT
Sample Output
http://acm.ashland.edu/ http://acm.baylor.edu/acmicpc/ http://acm.ashland.edu/ http://www.acm.org/ Ignored http://acm.ashland.edu/ http://www.ibm.com/ http://acm.ashland.edu/ http://www.acm.org/ http://acm.ashland.edu/ http://www.ibm.com/ Ignored
这里给出我自己的实现:
#include <iostream> #include <stack> #include <string.h> #include <stdio.h> using namespace std; typedef enum COMMAND { VISIT,BACK,FORWARD,QUIT, END }COMMAND; const char *cmd_list[] = { "VISIT", "BACK", "FORWARD","QUIT" }; int find(char *cmd) { for(int i = 0; i < END; i++) if(!strcmp(cmd_list[i], cmd)) return i; return -1; } void prasecmd(const char *s, char *cmd, char *arg) { int i = 0; const char *p = s; while(*p != ' ' && *p != '\0') { p++; i++; } if(*p == '\0') { strcpy(cmd, s); return ; } strncpy(cmd, s, i); strncpy(arg, p+1, strlen(s)-i); } int main() { stack<string> ss; ss.push("http://www.acm.org"); stack<string> stemp; string s; char cmd[10], arg[20]; int Cmd; while(getline(cin,s)) { bzero(cmd,sizeof(cmd)); bzero(arg, sizeof(arg)); prasecmd(s.c_str(), cmd, arg); Cmd = find(cmd); if(Cmd == -1) break; switch(Cmd) { case VISIT: { if(*arg != '\0') { ss.push(arg); cout<<arg<<endl; break; } else return 0; } case BACK: { stemp.push(ss.top()); ss.pop(); if(ss.empty()) { cout<<"Ignored"<<endl; ss.push(stemp.top()); stemp.pop(); break; } cout<<ss.top()<<endl; break; } case FORWARD: { if(!stemp.empty()) { ss.push(stemp.top()); stemp.pop(); cout<<ss.top()<<endl; break; } else { cout<<"Ignored"<<endl; break; } } case QUIT:cout<<"Ignored"<<endl;return 0;; } } return 0; }
自己实现的代码是有问题的:
1.当向前和向后的过程又重新VISIT了,对于这个问题,该程序是错误的
2.c和c++乱套了,代码风格不好
看了一个人写的,感觉还是不错的
#include <iostream> #include <stack> using namespace std; int main() { string current = "http://www.acm.org"; string text; stack<string> backward; stack<string> forward; forward.push(current); while(getline(cin, text)) { if(text == "QUIT") break; else if(text == "BACK") { if(backward.empty()) cout<<"Ignored"<<endl; else { forward.push(current); current = backward.top(); backward.pop(); cout<<current<<endl; } } else if(text == "FORWARD") { if(forward.empty()) cout<<"Ignored"<<endl; else { backward.push(current); current = forward.top(); forward.pop(); cout<<current<<endl; } } else { while(!forward.empty()) forward.pop(); backward.push(current); current = text.substr(6); cout<<current<<endl; } } return 0; }
使用一个current作为当前的URL,然后前后访问两个不同的stack,代码风格也比较不错,另外二叉树的后续遍历也使用了双栈法