问题描述:
给定一个只包括‘[’,‘]’,‘{’,‘}’,‘(’,‘)’的字符串s,判断字符串是否有效。
有效字符串需满足:
1. 左括号必须用相同类型的右括号闭合。
2. 左括号必须以正确的顺序闭合。
示例1:
输入:s=“()”
输出:ture
示例2:
输入:s=“()[]{}”
输出:true
示例3:
输入:s=“([”
输出:false
示例4:
输入:s=“([)]”
输出:false
解题思路:
因为上下括号一定是连在一起的,需要取出所存放的上括号与所输入的下一个字符比较,后入的先出,这里就符合栈的性质,故解此题时需要先创建一个栈。当输入的时上括号时,就存入栈中,如果输入的是下括号,就拿出上一个存入栈中的字符,将其与所输入的字符比较即可
注意:
1. 当只输入上括号时,最后要判断栈是否为空,栈不为空,说明只有上括号,就不满足题意
2. 当只输入下括号时,若不加处理,会直接进行删除操作,但此时栈中无元素,故会因为断言而终止程序,此时就要判断输入数据时,栈是否为空,栈为空,说明没有上括号,销毁栈,并直接返回false
3. return前记得一定要先销毁栈,防止内存泄露。
代码如下:
#include<stdio.h>
#include<stdbool.h>
#include<assert.h>
#include<stdlib.h>
typedef char STDataType;
typedef struct Stack
{
STDataType* a;
int top;//栈顶
int capacity;
}ST;
//初始化
void StackInit(ST* ps);
//销毁栈
void StackDestory(ST* ps);
//栈顶插入数据(入栈)
void StackPush(ST* ps, STDataType x);
//出栈
void StackPop(ST* ps);
STDataType StackTop(ST* ps);
int StackSize(ST* ps);
bool StackEmpty(ST* ps);
//初始化
void StackInit(ST* ps)
{
assert(ps);
ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
if (ps->a == NULL)
{
printf("malloc fail\n");
exit(-1);//不是正常结束
}
ps->capacity = 4;
ps->top = 0;//意味着top指向的是栈顶元素的下一位,若为-1,则top指向的是栈顶元素
}
//销毁栈
void StackDestory(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 0;
}
//栈顶插入数据(入栈)
void StackPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(STDataType));
if (tmp == NULL)
{
printf("realloc fail\n");
exit(-1);//不是正常结束
}
else
{
ps->a = tmp;
ps->capacity *= 2;
}
}
ps->a[ps->top] = x;
ps->top++;
}
//出栈
void StackPop(ST* ps)
{
assert(ps);
assert(ps->top > 0);//栈空了,调用pop,直接中止程序报错
ps->top--;
}
//返回栈顶元素
STDataType StackTop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
return ps->a[ps->top - 1];
}
//返回栈中数据的数量
int StackSize(ST* ps)
{
assert(ps);
return ps->top;
}
//判断是否为空
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
//有效的括号
bool isValid(char* s)
{
ST st;
StackInit(&st);
while (*s != '\0')
{
switch (*s)
{
case '{':
case'[':
case'(':
StackPush(&st, *s);
s++;
break;
case '}':
case ']':
case ')':
{
//只输入下括号
if (StackEmpty(&st))
{
StackDestory(&st);
return false;
}
//在switch中定义局部变量要加花括号,否则会出现声明不能包含标签的错误
char top = StackTop(&st);//记录上一个进栈的符号
StackPop(&st);
if ((*s == '}' && top != '{')
|| (*s == ']' && top != '[')
|| (*s == ')' && top != '('))
{
StackDestory(&st);
return false;
}
else//匹配
{
s++;
}
break;
}
default:
break;
}
}
//只输入上括号
bool ret = StackEmpty(&st);
StackDestory(&st);
return ret;
}