#include <stdio.h>
#include <stdlib.h>
// 栈 后进先出
typedef int SElemType; // 任意数据类型
typedef int Status; // 函数返回数据类型
#define TRUE 1
#define OK 1
#define FALSE 0
#define ERROR -1
#define OVERFLOW -2
#define STARKINIT 100
#define INCREMENT 10
typedef struct{
SElemType *base; // 在栈构造之前和销毁之后,值为NULL
SElemType *top; // 栈顶指针
int stackSize; // 当前已分配的存储空间(单位:元素)
}SqStack;
// 构造一个空栈
Status InitStact(SqStack *S){
// base申请初始长度的存储空间,并指向第一个地址
S->base = (SElemType *)malloc(STARKINIT * sizeof(SElemType));
if(!S->base) exit(OVERFLOW);
S->top = S->base;
S->stackSize = STARKINIT;
return OK;
}
// 销毁栈
Status DestroyStack(SqStack *S){
free(S);
return OK;
}
// 将S置空
Status ClearStack(SqStack *S){
S->top = S->base;
return OK;
}
// 判断S是否为空,是返回TRUE,否返回FALSE
Status StackEmpty(SqStack S){
if(S.top == S.base) return TRUE;
return FALSE;
}
// 返回S的元素个数
int StackLength(SqStack S){
return S.top-S.base;
}
// 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
Status GetTop(SqStack S, SElemType *e){
// 若头指针还是指向第一个,说明根本没有存过数据元素,即为空
if(S.top == S.base) return ERROR;
// 不为空e指向栈顶地址(即为top-1的指针指向的地址)
*e = *(S.top-1);
return OK;
}
// 插入元素e为新的栈顶元素
Status Push(SqStack *S, SElemType e){
// 若top指向已经大于当前已申请的存储空间
if(S->top - S->base >= S->stackSize){
// 申请新的存储空间
S->base = (SElemType *)realloc(S->base,(S->stackSize + INCREMENT)* sizeof(SElemType));
if(!S->base) exit(OVERFLOW);
// top指向新申请部分的指针的第一位
S->top = S->base + S->stackSize;
S->stackSize += INCREMENT;
}
// 在当前指针位置存入数据元素e然后top++
*S->top++ = e;
return OK;
}
// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
Status Pop(SqStack *S, SElemType *e){
if(S->top == S->base) return ERROR;
// e获得栈顶元素值,然后top--
*e = * --S->top;
return OK;
}
// 从栈底到栈顶依次对栈中每个元素调用函数visit()。一旦visit失败,则操作失败
Status StackTraverse(SqStack S, Status (*visit)()){
}
// 将输入的任意非负十进制整数转换成八进制
void conversation(){
SqStack S;
InitStact(&S);
int n;
printf("请输入一个非负十进制整数:");
scanf("%d",&n);
while(n){
Push(&S,n%8);
n = n/8;
}
printf("对应八进制整数:");
while(!StackEmpty(S)){
SElemType e;
Pop(&S,&e);
printf("%d",e);
}
printf("\n");
}
// 括号匹配的检验
void getBracket(){
SqStack S;
InitStact(&S);
printf("请输入括号总数:");
int n,f=1;
scanf("%d",&n);
if(n%2 != 0){
printf("括号总数非法!\n");
exit(0);
}
printf("请依次输入括号:");
char c;
rewind(stdin);
while(n){
SElemType e;
scanf("%c",&c);
e = c;
if(f == 0);
else if(c == '[' || c == '(') Push(&S,c);
else{
GetTop(S,&e);
if((c==']' && e=='[') || (c==')' && e=='(')) Pop(&S,&e);
else f=0;
}
--n;
}
if(f) printf("括号匹配合法!\n");
else printf("括号匹配非法!\n");
}
// 行编辑程序
void LineEdit(){
SqStack S;
InitStact(&S);
char ch = getchar();
SElemType c;
while(ch != EOF){
while(ch != EOF && ch != '\n'){
switch(ch){
case '#':Pop(&S,&c);break;
case '@':ClearStack(&S);break;
default:Push(&S,ch);
}
ch = getchar();
}
// 存进缓冲区,我懒得写了,直接输出
while(!StackEmpty(S)){
SElemType e;
Pop(&S,&e);
printf("%c",e);
}
printf("\n");
ClearStack(&S);
if(ch != EOF) ch = getchar();
}
DestroyStack(&S);
}
int main()
{
LineEdit();
SqStack S;
InitStact(&S);
printf("请输入需要插入栈的数据元素的个数:");
int n;
scanf("%d",&n);
printf("请输入数据元素:");
SElemType e;
for(int i=0; i<n; i++){
scanf("%d",&e);
Push(&S,e);
}
printf("共插入了%d个数据元素\n",StackLength(S));
printf("栈内的元素为:");
for(int i=0; i<n; i++){
Pop(&S,&e);
printf("%d ",e);
}
printf("\n");
return 0;
}