LeetCode 20.有效括号 详解(c语言实现) (⌯꒪꒫꒪)੭

news2024/11/20 3:32:16

题目详情:

 思路:Step1:如果是左括号,入栈

          Step2:如果是右括号,就出栈顶的元素与右括号进行比对,如果匹配,继续,直到都匹配成功结束。否则退出,直接返回false.

栗子:1.  {[()]}      左括号  '{' '[' '('  入栈后与栈顶的右括号 )')'  ']' '}' 依次进行匹配,结果发现匹配,返回true.

2.  [(]}    左括号 '['  '('  入栈,遇到右括号 ']' 与栈顶的左括号 '('   匹配,匹配不上,返回false.

注意:无论匹配或者不匹配,都要摧毁栈,防止内泄漏

用c语言实现栈,没法直接引用,这里需要自己创建一个栈,在完成上述操作。如果还不会栈的小伙伴可以看看我的这篇博客 【数据结构】栈【详解】૮₍ ˃ ⤙ ˂ ₎ა-CSDN博客

 栈的实现:

typedef int STDataType;
typedef struct Stack//栈的声明与定义
{
	STDataType* a;//定义一个指针,用于后续存储空间
	int top;
	int capacity;
}ST;
//初始化栈
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;
}
//摧毁栈
void StackDestory(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 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);
	// 栈空了,调用Pop,直接中止程序报错
	assert(ps->top > 0);
    //出栈直接让栈顶减一
	//ps->a[ps->top - 1] = 0;
	ps->top--;
}
//返回栈顶的元素
STDataType StackTop(ST* ps)
{
	assert(ps);
	// 栈空了,调用Top,直接中止程序报错
	assert(ps->top > 0);

	return ps->a[ps->top - 1];
}
//返回栈的大小
int StackSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

 括号匹配函数的实现:

//测试运行函数
bool isValid(char* s) 
{
    ST st;
    StackInit(&st);
    while(*s!='\0')
    {   //通过指针来遍历数组,直到终止
//这里判断字符,左括号进栈,右括号出栈
         switch(*s)
         {
             case '{':
             case '[':
             case '(':
             {
                 StackPush(&st,*s);
                 ++s;
                 break;//每次进栈就进行下一次循环,同时++s
             }
             case '}':
             case ']':
             case ')':
             {//如果没有左括号,就说明只有右括号,栈内为空,就直接返回false
             //记得要摧毁栈,防止内存泄漏
                 if(StackEmpty(&st))
                 {
                     StackDestory(&st);
                     return false;
                 }
                 //若栈不为空,就   取栈顶元素进行比对
                 //若为预期对应的右括号,匹配成功,同时++s,移向下一个位置继续匹配
                 char top=StackTop(&st);
                 StackPop(&st);
                 //不匹配就返回flase
                 if((*s=='}' && top!='{')
                 || (*s==']' && top!='[')
                  || (*s==')' && top!='('))
                  {
                      StackDestory(&st);
                      return false;
                  }
                  else
                  {
                    ++s;
                  }
             }
             default:
             break;
         }
    }
    //若当前栈为空,说明已经匹配完成,都匹配,返回true
    bool ret=StackEmpty(&st);
    StackDestory(&st);
    return ret;
}

如代码所示:通过遍历*s,来进行括号的匹配。如果字符是左括号就入栈StackPush,并使s++。如果只有右括号而没有左括号,说明栈为空,这时直接摧毁栈并返回false。接着依次取栈顶元素与当前右括号匹配,成功就继续,直到最后一个匹配完成(这时判断条件是完成上述操作后StackEmpty是真),返回true,否者返回false。

最后完整代码: 

typedef int STDataType;
typedef struct Stack//栈的声明与定义
{
	STDataType* a;//定义一个指针,用于后续存储空间
	int top;
	int capacity;
}ST;
//初始化栈
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;
}
//摧毁栈
void StackDestory(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 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);
	// 栈空了,调用Pop,直接中止程序报错
	assert(ps->top > 0);
    //出栈直接让栈顶减一
	//ps->a[ps->top - 1] = 0;
	ps->top--;
}
//返回栈顶的元素
STDataType StackTop(ST* ps)
{
	assert(ps);
	// 栈空了,调用Top,直接中止程序报错
	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;//每次进栈就进行下一次循环,同时++s
             }
             case '}':
             case ']':
             case ')':
             {//如果没有左括号,就说明只有右括号,栈内为空,就直接返回false
             //记得要摧毁栈,防止内存泄漏
                 if(StackEmpty(&st))
                 {
                     StackDestory(&st);
                     return false;
                 }
                 //若栈不为空,就   取栈顶元素进行比对
                 //若为预期对应的右括号,匹配成功,同时++s,移向下一个位置继续匹配
                 char top=StackTop(&st);
                 StackPop(&st);
                 //不匹配就返回flase
                 if((*s=='}' && top!='{')
                 || (*s==']' && top!='[')
                  || (*s==')' && top!='('))
                  {
                      StackDestory(&st);
                      return false;
                  }
                  else
                  {
                    ++s;
                  }
             }
             default:
             break;
         }
    }
    //若当前栈为空,说明已经匹配完成,都匹配,返回true
    bool ret=StackEmpty(&st);
    StackDestory(&st);
    return ret;
}

博客到这里也是结束了,喜欢的小伙伴可以点赞加关注支持下博主,这对我真的很重要~~

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1358506.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#之反编译之路(一)

本文将介绍微软反编译神器dnSpy的使用方法 c#反编译之路(一) dnSpy.exe区分64位和32位,所以32位的程序,就用32位的反编译工具打开,64位的程序,就用64位的反编译工具打开(个人觉得32位的程序偏多,如果不知道是32位还是64位,就先用32位的打开试试) 目前只接触到wpf和winform的桌…

Redis (三)

1、redis复制 简单的概括就是主从复制,master以写为主,Slave以读为主,当master数据发生变化的时候,自动将更新的数据异步同步到其他的slave是数据库。 使用这种机制的话,可以做到读写分离,可以减轻主机负担…

DDoS攻击的多种方式

DDOS攻击指分布式拒绝服务攻击,即处于不同位置的多个攻击者同时向一个或数个目标发动攻击,或者一个攻击者控制了位于不同位置的多台机器并利用这些机器对受害者同时实施攻击。由于攻击的发出点是分布在不同地方的,这类攻击称为分布式拒绝服务…

大数据毕设分享 flink大数据淘宝用户行为数据实时分析与可视化

文章目录 0 前言1、环境准备1.1 flink 下载相关 jar 包1.2 生成 kafka 数据1.3 开发前的三个小 tip 2、flink-sql 客户端编写运行 sql2.1 创建 kafka 数据源表2.2 指标统计:每小时成交量2.2.1 创建 es 结果表, 存放每小时的成交量2.2.2 执行 sql &#x…

提升网络安全重要要素IP地址

在数字化时代,网络安全已经成为人们关注的焦点。本文将深入探讨网络安全与IP地址之间的紧密联系,以及IP地址在构建数字世界的前沿堡垒中的关键作用。 网络安全是当今数字社会中不可忽视的挑战之一。而IP地址,作为互联网通信的基础协议&#…

震惊!原来这就是JavaScript闭包的秘密

📢 鸿蒙专栏:想学鸿蒙的,冲 📢 C语言专栏:想学C语言的,冲 📢 VUE专栏:想学VUE的,冲这里 📢 CSS专栏:想学CSS的,冲这里 &#x1f4…

第一届能源电子产业创新大赛太阳能光伏赛道决赛及颁奖仪式在宜宾成功举办

在工业和信息化部电子信息司指导下,由工业和信息化部产业发展促进中心和宜宾市人民政府主办,宜宾市经济和信息化局、宜宾高新技术产业园区管理委员会承办的第一届能源电子产业创新大赛太阳能光伏赛道决赛及颁奖仪式于2024年1月3日-5日在宜宾市成功举办。…

DDIA 第十一章:流处理

本文是《数据密集型应用系统设计》(DDIA)的读书笔记,一共十二章,我已经全部阅读并且整理完毕。 采用一问一答的形式,并且用列表形式整理了原文。 笔记的内容大概是原文的 1/5 ~ 1/3,所以你如果没有很多时间…

2023年后,AI 还有什么研究方向有前景?

什么是AI ​ AI代表人工智能,它是指通过计算机科学技术使机器能够执行需要智力的任务的一种技术。这些任务包括学习、推理、问题解决和感知等,通常是人类智能的表现。人工智能的目标是使计算机系统能够执行需要人类智力的任务,而不需要人类的…

C语言实用第三方库Melon开箱即用之多线程模型

在之前的文章中(开发利器——C 语言必备实用第三方库),笔者介绍了一款Linux/UNIX下C语言库Melon的基本功能,并给出了一个简单的多进程开箱即用的例子。 本文将给大家介绍Melon中多线程的使用方法。 在Melon中有三种多线程模式&a…

点对点SDWAN组网:通过专线连接实现企业分支互联

点对点SDWAN是一种通过软件定义网络技术将企业分支互联的组网解决方案。在点对点SDWAN中,企业分支通过专线连接实现互联,以满足对网络性能和可靠性的要求。 传统的WAN架构通常使用MPLS(多协议标签交换)技术来实现企业分支的互联。…

TransmittableThreadLocal使用踩坑

背景:为了获取相关字段方便,项目里使用了TransmittableThreadLocal上下文,在异步逻辑中get值时发现并非当前请求的值,且是偶发状况(并发问题)。 发现:TransmittableThreadLocal是阿里开源的可以实现父子线程值传递的工…

鸿蒙系列--动态共享包的依赖与使用

一、前言 HarmonyOS的共享包相当于Android的Library,在HarmonyOS中,给开发者提供了两种共享包,HAR(Harmony Archive)静态共享包,和HSP(Harmony Shared Package)动态共享包 区别&…

记一次 .NET 某新能源材料检测系统 崩溃分析

一:背景 1. 讲故事 上周有位朋友找到我,说他的程序经常会偶发性崩溃,一直没找到原因,自己也抓了dump 也没分析出个所以然,让我帮忙看下怎么回事,那既然有 dump,那就开始分析呗。 二&#xff…

计算机创新协会冬令营——暴力枚举题目05

这道题挺基础但是挺多坑的。(•́へ•́╬) 题目 204. 计数质数 - 力扣(LeetCode) 给定整数 n ,返回 所有小于非负整数 n 的质数的数量 。 示例 示例 1: 输入:n 10 输出:4 解释:小于 10 的质…

具有大电流,双通道 12V,短地短电源保护等功能的国产芯片GC8549 可替代ONSEMI的LV8548/LV8549

GC8549 可以工作在 3.8~12V 的电源电压上,每 通道能提供高达 1.5A 持续输出电流或者 2.5A 峰值 电流,睡眠模式下功耗小于 1uA。具有 PWM(IN/EN)输入接口,与行业标 准器件兼容,并具有过温保护,欠压保护&…

信息系统项目管理师好考吗?知识点分析与讲解,码住!

科目一:综合知识考试 科目一考试是由选择题组成的,共有75道题目。考试时间为早上9点到11点半,可以提前交卷,通常11点左右就能离开考场。对于会做的题目,要及时解答,对于不会做的题目,花费过多时…

QC/PD快充电源产品MOS选型分析

• 原边650-700V SJ MOSFET采用低FOM值的ESM 技术,有利于提高系统效 率, 以及更佳的EAS和EMI等特性,对于一些不含PFC电路的系统更友好。 • 副边采用低FOM值的SGT同步整流电路,相比肖特基二极管整流能有更低的 损耗,有…

pinia 给 state 指定变量类型

pinia 给 state 指定变量类型 问题描述 自从用 vitetsvue3 以来,我一直有一个很大的疑问,就是 pinia 中的 state 变量类型该从哪定义,如何定义它? 因为我在使用未定义类型的 state 变量的时候一直会有一个提示,提示说…

JAVA集合框架总结

集合框架概述 1.1 生活中的容器 1.2 数组的特点与弊端 一方面,面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储。另一方面,使用数组存储对象方面具有一些弊端,而Java 集合就…