有效的括号: 题目链接
栈: 笔记链接
思路
如题所说,有效字符串必须是:其内部的左括号紧挨着相同类型的有括号
那么创建一个栈,
如果是“(”或者“[”或者“{”,那么将其压入栈中;
如果是“)”或者“]”或者“}”,那么将其与上一个压入栈中的字符进行比对。若符合有效字符串的性质,则继续比对;若不符合则返回false
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;//top所标识的是最后一个数据的下一个位置
int capacity;
}Stack;
void StackInit(Stack* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
void StackPush(Stack* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;//如果栈中没有数据,那么给它四个数据的空间;如果有,那么在原有的基础上扩大二倍
STDataType* temp = realloc(ps->a, sizeof(STDataType) * newCapacity);//用temp指向扩容后的空间,回头再把它赋给ps->a
if (temp == NULL)//realloc可能会失败,失败会返回空指针
{
printf("realloc fail\n");
exit(-1);
}
ps->a = temp;
ps->capacity = newCapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
bool StackEmpty(Stack* ps)
{
assert(ps);
return ps->top == 0;
}
void StackPop(Stack* ps)
{
assert(ps);
assert(!StackEmpty(ps));
ps->top--;
}
STDataType StackTop(Stack* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top - 1];
}
int StackSize(Stack* ps)
{
assert(ps);
return ps->top;
}
void StackInit(Stack* ps);
void StackDestroy(Stack* ps);
void StackPush(Stack* ps, STDataType x);
void StackPop(Stack* ps);
void Stackp(Stack* ps);
STDataType StackTop(Stack* ps);
bool StackEmpty(Stack* ps);
int StackSize(Stack* ps);
bool isValid(char * s){
Stack st;
StackInit(&st);
while (*s)
{
if (*s == '(' || *s == '[' || *s == '{')
{
StackPush(&st, *s);
++s;
}
else
{
if (StackEmpty(&st))//如果第一个入栈的数据是(、[、{,那么字符串s必定是无效字符串
{
return false;
}
STDataType top = StackTop(&st);
StackPop(&st);
if ((top == '{' && *s == '}')
||(top == '[' && *s == ']')
||(top == '(' && *s == ')'))
{
++s;
}
else
{
return false;
}
}
}
//判断栈为不为空,以确定所有的扩号都已经匹配
//如果字符串s是无效字符串,那么在栈中会有未匹配的(或【或{。反言之如果字符串是有效的,那么这里的栈一定是空的
bool ret = StackEmpty(&st);
StackDestroy(&st);//这里栈已经销毁了,所以不能直接return,因此定义了一个ret来接受、返回
return ret;
}