顺序栈
【Elemtype为数据类型】
顺序栈本身是操作受限制的顺序表,只能在栈顶做插入删除,称入栈出栈,因为操作受限,算法相较普通顺序表简单。
创建
typedef struct { Elemtype *base; Elemtype *top; int maxsize; }SQstack;
|
初始化
bool initstack(SQstack &sq) { sq.base=new Elemtype[MAXSIZE]; if(!sq.base) return false; sq.top=sq.base; sq.maxsize=MAXSIZE; return true; }
|
入栈(从栈顶插入)
bool Push(SQstack &sq,Elemtype e) { if(sq.top-sq.base>=sq.maxsize) return false; *sq.top=e; sq.top++; return true; }
|
出栈(从栈顶删除)
bool Pop(SQstack &sq,Elemtype &e) { if(sq.top==sq.base) return false; sq.top--; e=*sq.top; return true; }
|
取栈顶(取值)
Elemtype gettop(SQstack &sq)
{ if(sq.top!=sq.base) { return *(sq.top-1); } }
|
链式栈
【Elemtype为数据类型】
在无法估计栈数据量时,通常采用链式栈,而且因为栈的主要操作是插入和删除,所以用链表的头部作栈顶更加方便。
创建
typedef struct Lnode { Elemtype data; struct Lnode *next; }*Linkstack;
|
初始化
bool initstack(Linkstack &ls) { ls=NULL; return true; }
|
入栈(从栈顶插入)
bool Push(Linkstack &ls,Elemtype e) { Lnode *p; p=new Lnode; p->data=e; p->next=ls; ls=p; return true; }
|
出栈(从栈顶删除)
bool Pop(Linkstack &ls,Elemtype &e) { if(ls==NULL) return false; e=ls->data; Lnode *p=ls; ls=ls->next; delete p; return true; }
|
取栈顶(取值)
Elemtype gettop(Linkstack &ls) { if(ls!=NULL) return ls->data; }
|
实际题目
R7-1 堆栈操作合法性 (20 分)
假设以S和X分别表示入栈和出栈操作。如果根据一个仅由S和X构成的序列,对一个空堆栈进行操作,相应操作均可行(如没有出现删除时栈空)且最后状态也是栈空,则称该序列是合法的堆栈操作序列。请编写程序,输入S和X序列,判断该序列是否合法。
输入格式:
输入第一行给出两个正整数N和M,其中N是待测序列的个数,M(≤50)是堆栈的最大容量。随后N行,每行中给出一个仅由S和X构成的序列。序列保证不为空,且长度不超过100。
输出格式:
对每个序列,在一行中输出YES如果该序列是合法的堆栈操作序列,或NO如果不是。
输入样例:
4 10 SSSXXSXXSX SSSXXSXXS SSSSSSSSSSXSSXXXXXXXXXXX SSSXXSXXX
|
输出样例:
解法:
#include<iostream> #include<string> using namespace std;
typedef struct { char *top; char *base; int size; }SQstack;
bool init(SQstack &sq,int m) { sq.base=new char[m]; if(!sq.base) return false; sq.top=sq.base; sq.size=m; return true; }
bool pop(SQstack &sq) { if(sq.top==sq.base) return false; sq.top--; return true; }
bool push(SQstack &sq,char e) { if(sq.top-sq.base==sq.size) return false; *sq.top=e; sq.top++; return true; }
int main() { int n,m,i,j=0; bool flag=true; cin>>n>>m; string str; SQstack L; for(i=0;i<n;i++) { init(L,m); cin>>str; flag=true; for(j=0;str[j]!='\0';j++) { if(str[j]=='S') { flag=push(L,str[j]); } if(str[j]=='X') { flag=pop(L); } } if(L.base==L.top&&flag==true) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
|
R7-2 回文判断 (20 分)
回文是指正读反读均相同的字符序列,如“abba”和“abdba”均是回文,但“good”不是回文。编写一个程序,使用栈判定给定的字符序列是否为回文。
输入格式:
输入待判断的字符序列,按回车键结束,字符序列长度<20。
输出格式:
若字符序列是回文,输出“YES”;否则,输出“NO”。
输入样例:
输出样例:
解法:
#include<iostream> #include<string> using namespace std;
typedef struct { char *top; char *base; int size; }SQstack;
bool init(SQstack &sq) { sq.base=new char[20]; if(!sq.base) return false; sq.top=sq.base; sq.size=20; return true; }
bool push(SQstack &sq,char a) { if(sq.top-sq.base==sq.size) return false; *sq.top=a; sq.top++;
return true; }
bool pop(SQstack &sq) { if(sq.top==sq.base) return false; sq.top--;
return true; }
bool gettop(SQstack &sq,int &a) { if(sq.base==sq.top) return false; a=*(sq.top-1); return true; }
int main() { SQstack L; init(L); string str; int i,n=0,a; bool flag=true; cin>>str; n=str.size(); if(n%2==0) {
for(i=0;i<n;i++) { if(i<n/2) push(L,str[i]); else {
gettop(L,a);
if(str[i]==a) pop(L); else { flag=false; break; } } } } else {
for(i=0;i<n;i++) { if(i==(n-1)/2); else { if(i<(n-1)/2) push(L,str[i]); else { gettop(L,a);
if(str[i]==a) pop(L); else {
flag=false; break; } } } } } if(flag==true) cout<<"YES"<<endl; else cout<<"NO"<<endl; }
|
R7-3 括号匹配 (20 分)
检查一段C语言代码的小括号( )、 中括号 [ ] 和大括号{ } 是否匹配。
输入格式:
在一行中输入一段C语言代码,长度不超过1000个字符(行末以换行符结束)。
输出格式:
第一行输出左括号的数量和右括号的数量,中间以一个空格间隔。
若括号是匹配的,在第二行打印YES,否则打印NO。
输入样例1:
for(int i=0; i<v; i++){ visited[i] = 0; for(int j=0; j<v; j++) scanf("%d",&(g->Adj[i][j])); }
|
输出样例1:
输入样例2:
for(int i=0; i<v; i++) a(i]=0;
|
输出样例2:
解法:
#include<iostream> #include<string> using namespace std;
typedef struct { char *top; char *base; int size; }SQstack;
bool init(SQstack &sq) { sq.base=new char[500]; if(!sq.base) return false; sq.top=sq.base; sq.size=500; return true; }
bool push(SQstack &sq,char a) { if(sq.top-sq.base==sq.size) return false; *sq.top=a; sq.top++; return true; }
bool pop(SQstack &sq) { if(sq.top==sq.base) return true; sq.top--; return true; }
bool gettop(SQstack &sq,char &a) { if(sq.top==sq.base) return false; a=*(sq.top-1); return true; }
int main() { SQstack L; init(L); char a='1'; bool flag=true; int i,left=0,right=0,k=0; char str[500]; for(i=0;i<500;i++) { cin>>str[i]; k++; } for(i=0;i<k;i++) { if(str[i]=='('||str[i]=='['||str[i]=='{') { left++; push(L,str[i]); } else { if(str[i]==')'||str[i]==']'||str[i]=='}') { right++; gettop(L,a); if((str[i]==')'&&a=='(')||(str[i]==']'&&a=='[')||(str[i]=='}'&&a=='{')) { pop(L); } else flag=false; } } } if(L.top!=L.base) flag=false; if(left==0&&right==0) flag=true; cout<<left<<" "<<right<<endl; if(flag) cout<<"YES"; else cout<<"NO"; return 0; }
|