括号匹配问题 <难度系数⭐>

183 阅读2分钟

「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

📝 题述:给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

1️⃣ 左括号必须用相同类型的右括号闭合。

2️⃣ 左括号必须以正确的顺序闭合。

💨 示例1: 输入:s = "()" 输出:true

💨 示例2: 输入:s = "()[]{}" 输出:true

💨 示例3: 输入:s = "(]" 输出:false

💨 示例4: 输入:s = "([)]" 输出:false

💨 示例5: 输入:s = "{[]}" 输出:true

🧷 平台:Visual studio 2017 && windows

🔑 核心思想:这里我们自己实现一个栈(具体看下图) 请添加图片描述

leetcode原题

//结构体
typedef char STDatatype;
typedef struct Stack
{
    STDatatype* a; //指向动态开辟的空间
    int top; //栈顶
    int capacicy; //容量
}ST;
//函数 
//注意链表和顺序表我们写Print,但是栈不写,因为如果栈可以Print的话,就不符合后进先出了
	//初始化
void StackInit(ST* ps);
	//插入
void StackPush(ST* ps, STDatatype x);
	//判空
bool StackEmpty(ST* ps);
	//删除
void StackPop(ST* ps);
	//长度
int StackSize(ST* ps);
	//栈顶
STDatatype StackTop(ST* ps);
	//销毁
void StackDestory(ST* ps);

bool isValid(char* s)
{
    ST st;
    StackInit(&st); 
    //match记录真假
    bool match = true;
    while(*s)
    {
        //如果*s等于左括号其中一个则入栈
        if(*s == '[' || *s == '(' || *s == '{')
        {
            StackPush(&st, *s);
            ++s;
        }
        //否则*s等于右括号,出栈里的数据进行匹配
        else
        {
            //如果字符串里只有右括号时,返回false
            if(StackEmpty(&st))
            {
                match = false;
                break;
            }
            //取栈顶的数据 (ch是已经入栈的数据,*s是还未入栈的数据) 
            char ch = StackTop(&st);
            //出栈 '{[]}'为了取上一个数据
            StackPop(&st); 
            //比较
                //不匹配
            if((*s == ']' && ch != '[') 
            || (*s == '}' && ch != '{')
            || (*s == ')' && ch != '('))
            {
                match = false;
                break;                
            }
                //匹配
            else
            {
                ++s;
            }
        }
    }
    if (match == true)
    {
        //如果字符串只有一个左括号时,StackEmpty会返回false
        match = StackEmpty(&st);
    }
    //统一回收
    StackDestory(&st);
    return match;
}

void StackInit(ST* ps)
{
    assert(ps);
    //初始化
    ps->a = NULL;
    ps->top = 0;
    ps->capacicy = 0;
}
void StackPush(ST* ps, STDatatype x)
{
    assert(ps);
    //检查空间,满了就增容
    if (ps->top == ps->capacicy)
    {
	//第一次开辟空间容量为4,其它次容量为当前容量*2
	int newcapacity = ps->capacicy == 0 ? 4 : ps->capacicy * 2;
	//第一次开辟空间,a指向空,realloc的效果同malloc
	STDatatype* tmp = realloc(ps->a, sizeof(STDatatype) * newcapacity);
	//检查realloc
            //realloc失败
	if (tmp == NULL)
	{
            printf("realloc fail\n");
            exit(-1);
	}
            //realloc成功
	ps->a = tmp;
	ps->capacicy = newcapacity;
    }
    //插入数据 
    ps->a[ps->top] = x;
    ps->top++;
}
bool StackEmpty(ST* ps)
{
    assert(ps); 
    //等于0是真,否则为假
    return ps->top == 0;
}
void StackPop(ST* ps)
{
    assert(ps);
    //删除的话得保证指向的空间不为空
    assert(!StackEmpty(ps));
    //删除
    --ps->top;
}

STDatatype StackTop(ST* ps)
{
    assert(ps);
    //找栈顶的话得保证指向的空间不为空
    assert(!StackEmpty(ps));
    //此时的top-1就是栈顶数据
    return ps->a[ps->top - 1];
}
void StackDestory(ST* ps)
{
    assert(ps);
    //a为真代表它指向动态开辟的空间
    if (ps->a)
    {
	free(ps->a);
    }
    ps->a = NULL;
    ps->top = 0;
    ps->capacicy = 0;
}

int main()
{
    char arr[] = "{[]}";
    printf("%d\n", isValid(arr));
    return 0;
}