注意:
只能在栈顶插入,删除,访问
满足先进后出的原则
三种主要操作
把一个元素推入栈 push O(1)
把栈顶元素弹出 pop O(1)
获得栈顶元素的值 top O(1)
可以使用数组模拟或使用 stl 中的 stack
创建
const int length = 100;
int stack [ length ] ;
int size ;
把一个元素推入栈 push
void push( int val ) {
stack [ size + 1] = val ;
size++;
}
把栈顶元素弹出 pop
void pop () {
stack [ size ] = 0; // 非必要
size −−;
}
获得栈顶元素的值 top
int top () {
i f ( size == 0) return −1;
return stack [ size ] ;
}
栈的基本代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<queue> using namespace std; const int n=10; int a[n];//栈的创建 int size,x; void push(int x) { a[size+1]=x; size++; }//插入一个元素x void pop() { a[size]=0; size--; } //弹出栈顶元素 int top() { if(size==0) return -1; else return a[size]; } //获得栈顶值 int main() { for(int i=1;i<=n;i++) { size++; scanf("%d",&a[i]); } scanf("%d",&x); push(x); pop(); printf("%d\n",top()); for(int i=1;i<=n;i++) printf("%d ",a[i]); }
多种括号匹配
定义满足以下规则字符串为规则序列,否则不是规则序列:
1.空序列是规则序列;
2.如果S是规则序列,那么(S),[S],{S}和<S>也是规则序列;
3.如果A和B都是规则序列,那么AB也是规则序列。
例如,下面的字符串都是规则序列:
(),[],(()),([]),()[],()[()],{{}}<>,([]<>{{}}),<<{}>>
而以下几个则不是:
(,[,],)(,()),([(),<<,{(}),<{}>)
现在,给你一些由"("、")"、"["、"]"、"{"、"}"、"<"、">"构成的字符串,请判断该字符串是否为规则序列。
输入描述 Input Description
第一行:一个正整数N,表示测试数据组数;
接下来N行:每行一个括号序列(长度不超过L)。
输出描述 Output Description
共N行:对于每一个括号序列,判断其是否规则。
规则输出TRUE,否则输出FALSE。
样例输入 Sample Input
2
{()}<<>>
{{{{{}}}}
样例输出 Sample Output
TRUE
FALSE
参考程序
#include<iostream> #include<cstring> using namespace std; char str[2000010]; char zhan[2000010]; int n,h,q=0; bool judge() { q=0; int len=strlen(str); for (int i=0; i<=len-1; i++) { if (str[i]=='{'||str[i]=='['||str[i]=='('||str[i]=='<') zhan[++q]=str[i]; else if ((zhan[q]=='{'&&str[i]=='}')||(zhan[q]=='['&&str[i]==']')||(zhan[q]=='('&&str[i]==')')||(zhan[q]=='<'&&str[i]=='>'))q--; else return false; } if (q)return false; else return true; } int main() { cin>>n; for (int i=1; i<=n; i++) { cin>>str; if(judge())cout<<"TRUE"; else cout<<"FALSE"; cout<<endl; } return 0; }
3137 栈练习1
题目描述 Description
给定一个栈(初始为空,元素类型为整数,且小于等于100),只有两个操作:入栈和出栈。先给出这些操作,请输出最终栈的栈顶元素。 操作解释:1表示入栈,2表示出栈
输入描述 Input Description
N(操作个数)
N个操作(如果是入栈则后面还会有一个入栈元素)
具体见样例(输入保证栈空时不会出栈)
输出描述 Output Description
最终栈顶元素,若最终栈空,输出”impossible!”(不含引号)
样例输入 Sample Input
3
1 2
1 9
2
样例输出 Sample Output
2
参考程序
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<stack> using namespace std; int n,a,b; stack<int>q; int size; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a); if(a==1) { scanf("%d",&b); q.push(b); } if(a==2) { q.pop(); } } if(!q.empty()) printf("%d",q.top()); else cout<<"impossible!"; return 0; }
(此题与栈练习1相比改了2处:1加强了数据 2不保证栈空时不会出栈)
给定一个栈(初始为空,元素类型为整数,且小于等于100),只有两个操作:入栈和出栈。先给出这些操作,请输出最终栈的栈顶元素。 操作解释:1表示入栈,2表示出栈
输入描述 Input Description
N(操作个数)
N个操作(如果是入栈则后面还会有一个入栈元素)
具体见样例(输入不保证栈空时不会出栈)
输出描述 Output Description
最终栈顶元素,若最终栈空,或栈空时有出栈操作,输出”impossible!”(不含引号)
样例输入 Sample Input
3
1 2
2
2
样例输出 Sample Output
impossible!
#include<iostream> #include<cstdio> #include<cstdlib> #include<stack> using namespace std; stack<int>s; int n,a,b; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a); if(a==1) { scanf("%d",&b); s.push(b); } if(a==2) { if(!s.empty()) s.pop(); else { printf("impossible!"); return 0; } } } if(!s.empty()) printf("%d",s.top()); else printf("impossible!"); return 0; }
比起第一题,本题加了另外一个操作,访问栈顶元素(编号3,保证访问栈顶元素时或出栈时栈不为空),现在给出这N此操作,输出结果。
输入描述 Input Description
N
N次操作(1入栈 2出栈 3访问栈顶)
输出描述 Output Description
K行(K为输入中询问的个数)每次的结果
样例输入 Sample Input
6
1 7
3
2
1 9
1 7
3
样例输出 Sample Output
7 7
#include <iostream> #include <cstdio> #include <cstring> #include <stack> using namespace std; int x,n,y,t = 1; stack< int >a; int main() { scanf("%d",&n); for(int i = 1; i <= n ; i ++) { scanf("%d",&x); if(x == 1) { scanf("%d",&y); a.push(y); } if(x==2) { if(a.empty()) { t = 0; break; } else a.pop(); } if(x==3) { printf("%d\n",a.top()); } } if(a.empty()) n++; else return 0; }