问题描述
假设⼀个算术表达式中可以包含三种括号:圆括号"("和")"、⽅括号"["和"]"和花括号"{"和"}",且三种 括号可按任意的次序,嵌套使⽤(如:...[...{...}...[...]...]...[...]...(...)...)。编写判别给定表达式中所含括号是 否正确配对出现的算法(已知表达式已存⼊数据元素为字符的顺序表中)。
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OK 1
#define OVERFLOW -2
#define ERROR 0
typedef char SElemType;
typedef int Status;
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
SqStack InitStack(SqStack S){
//构建空栈S
S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if (!S.base)
exit (OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return S;
}
void Push(SqStack *S,char e) {
//入栈
printf("待入栈:%c\n",e);
printf("3:%d %d\n",(*S).top-(*S).base,(*S).stacksize);
if ((*S).top-(*S).base>=(*S).stacksize){
//栈满,追加存储空间
(*S).base=(SElemType *)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(SElemType));
if (!(*S).base) exit(OVERFLOW);//存储分配失败
(*S).top=(*S).base+(*S).stacksize;
(*S).stacksize+=STACKINCREMENT;
}
printf("入栈前栈顶元素:%c\n",*((*S).top-1));
*(*S).top=e;//先赋值e,再加一位置后移
printf("已入栈:%c\n",*(*S).top);
(*S).top++;
printf("入栈后栈顶元素:%c\n",*((*S).top-1));
}
char Pop(SqStack (*S)){
//若栈不空,则删除栈顶元素并用e返回,返回OK;否则ERROR;
printf("删前栈顶元素:%c\n",*((*S).top-1));
if ((*S).top==(*S).base)
return ERROR;
(*S).top--;
printf("删后栈顶元素:%c\n",*((*S).top-1));
return *(*S).top;
}
bool IsEmpty(SqStack (*S)){
//判断栈是否为空
if ((*S).top==(*S).base)
return true;
return false;
}
bool isValid (char *s){
//括号配对
int i;
SqStack S;
S=InitStack(S);//若不返回S则S无改变
for (i=0; i<strlen(s); i++){
printf("%c\n",s[i]);
if (s[i]=='(')
Push(&S,')');//一定要记得用指针
else if (s[i]=='[')
Push(&S,']');
else if (s[i]=='{')
Push(&S,'}');
else if (s[i]==')'||s[i]==']'||s[i]=='}'){
if (IsEmpty(&S) || Pop(&S)!=s[i])//两个条件不可颠倒
return false;
}
else ;
}
//右符号已配对结束,左符号还有多余,错误
if(IsEmpty(&S))
return true;
return false;
}
int main(){
char *s;
s="(aj[dfs]){jkl;sdf()}aaa\n";
printf("%s",s);
if (isValid(s))
printf("true");
else
printf("false");
return 0;
}
原因分析:
提示:构建空栈S函数内外的S.top,S.base地址不同。
解决方案:
提示:初始化及对栈进行操作时要使用指针,&S做实参,*S做形参,自定义函数内用(*S).top,*(*S).top等.