当前位置: 首页 > news >正文

【栈OJ题解】有效的括号

目录

一、题目:

二、题目分析:

三、思路:

四、代码实现:


王德有话说:

        dear 盆友们,

        上一节,我们简述了数据结构栈的底层代码实现,下面,我们一起来探讨一下栈的OJ有效的括号的实现:

一、题目:

先带大家来回顾一下栈的底层实现:

//定义栈的结构
typedef char STDataType;
typedef struct Stack
{STDataType* arr;int top;//始终指向栈顶的位置int capacity;//栈的容量
}ST;void StackInit(ST* ps)
{ps->arr = NULL;ps->top = ps->capacity = 0;
}//入栈
void StackPush(ST* ps,STDataType x)
{assert(ps);if (ps->top == ps->capacity){//增容int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* tmp = (STDataType*)realloc(ps->arr,newcapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newcapacity;
}//走到这里,就说明空间是足够的,可以直接插入数据ps->arr[ps->top++] = x;
}//栈是否为空
bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}//出栈操作
void StackPop(ST* ps)
{assert(ps);//这里要判断一下栈是否为空if (!StackEmpty(ps)){//不为空才能继续往下走--ps->top;}
}//取栈顶元素
STDataType StackTop(ST* ps)
{assert(ps);return ps->arr[ps->top-1];
}//栈的销毁
void StackDestroy(ST* ps)
{if (ps->arr)free(ps->arr);ps->arr = NULL;ps->capacity = ps->top = 0;
}//获取栈中有效数据个数
int StackSize(ST* ps)
{assert(ps);return ps->top - 1;
}

二、题目分析:

  • 左括号必须与相同类型的右括号闭合;
  • 左右括号必须以正确的顺序闭合;
  • 每个右括号必须有相同类型的左括号与之闭合

有如下几个实例:"([])","()[]{}","({])","(",")"。

值得注意的是,本题与小、中、大括号的优先级无关,童鞋们可以忽略这一点~ 

三、思路:

  • 遍历数组
  • 左括号入栈
  • 右括号 取栈顶跟*pi进行匹配

首先,我们定义一个栈、一个char类型的指针pi(指向字符类型数组的第一个元素s),随后,遍历数组,这里可以用while,满足条件进入循环,不满足条件跳出循环,这里的条件是"*pi!='\0'"。

其次,在while循环中,我们使用if语句,如果遍历到的字符是左括号('('、'['、'{'以下均简称为左括号,右括号同样)就入栈,如果不是左括号,就进入else语句。

进入到else语句,一般有几种情况:

  • 一是并没有左括号入栈,栈为空,第一个字符就是右括号,这里要直接返回false

这里值得注意的一点是:返回false之前要将栈销毁。

  • 二是遍历完左括号之后遍历到了右括号,上述思路中,我们写到,如果遍历到了右括号,取栈顶,与右括号进行匹配,如果(   )或者[    ]  亦或者{     }, 匹配成功,出栈顶(在else语句中实现),继续遍历,这里要进行pi++的操作。

注意这里:上述提到的pi++的操作是在if else语句外,while循环里实现的,因为小编也是新手,在这里思考了一会。

看到这儿,细心的朋友可能会问了,如果遇到了 只有左括号,'(' 这种事例呢,该如何解决?

下面,我们来分析,如果字符串中只有左括号,遍历之后,*pi为'\0',跳出循环,此时判断栈是否为空,如果栈为空,说明匹配成功,因为匹配成功的左括号都会被销毁,如果栈中还留有括号,就说明未匹配成功,不符合“有效的括号”这一规则,返回false。

四、代码实现:

//借助数据结构栈来实现
bool isValid(char* s) {ST st;//定义一个栈StackInit(&st);//对栈进行初始化char*pi = s;//定义一个指针,准备遍历数组while(*pi!='\0')//进入数组{if(*pi=='('||*pi=='['||*pi=='{')//左括号入栈{StackPush(&st,*pi);}else{if(StackEmpty(&st))//判断栈为空的情况{return false;}char top = StackTop(&st);//如果是右括号,则出栈顶,与*pi进行匹配if((top=='('&& *pi!=')')||(top=='['&& *pi !=']')||(top=='{'&& *pi !='}')){StackDestroy(&st);return false;}StackPop(&st);}pi++;}bool ret  = StackEmpty(&st)?true:false;//栈不为空,说明只有左括号//返回false,因为匹配成功的左括号都被销毁了StackDestroy(&st);return ret;
}

http://www.xdnf.cn/news/630271.html

相关文章:

  • 6个月Python学习计划 Day 3
  • 力扣热题——查找包含给定字符的单词
  • 多模态智能体架构
  • 236.二叉树的最近公共祖先
  • Day35打卡 @浙大疏锦行
  • 深度解析NL2SQL:从语义理解到工程实践的全链路探索
  • DC-DC电路的自举电容电路原理
  • Linux(7)——进程(概念篇)
  • 介绍一下什么是反射(面试题详细讲解)
  • VBA 读取指定范围内的单元格数据,生成csv文件
  • 英语学习5.24
  • Java中是值传递还是引用传递 ?
  • vue2中el-table 实现前端分页
  • 5.Java 面向对象编程入门:类与对象的创建和使用​
  • uint8_t是什么数据类型?
  • WSL 基础命令
  • 整平机实战手册:从参数调试到工艺优化的全流程指南
  • “天启” AI 技术演进任重道远
  • 为什么我输入对了密码,还是不能用 su 切换到 root?
  • 推荐系统里真的存在“反馈循环”吗?
  • WordPress多语言插件安装与使用教程
  • 2025年电工杯数学建模B题【垃圾运输】原创论文分享
  • 医学影像科研概述与研究伦理
  • [软件测试_4] 沟通技巧 | 测试用例 | 设计方法
  • 大模型推理 memory bandwidth bound (5) - Medusa
  • 一本通1307:【例1.3】高精度乘法 1308:【例1.5】高精除
  • 矩阵乘法--Python
  • Linux—进程池实现
  • 技术文档炼金术:从混乱到优雅的知识封装
  • 嵌入式工程师常用软件