数据结构基础详解(C语言): 栈的括号匹配(实战)与栈的表达式求值特殊矩阵的压缩存储

news2024/12/25 22:08:53

文章目录

  • 栈的应用
    • 1.栈的括号匹配
    • 代码实战:
    • 问题分析:
    • 2.栈的表达式求值
      • 2.1 中缀、后缀、前缀表达式
      • 2.2 中缀表达式改写为后缀表达式(手算)
      • 2.3 后缀表达式的计算(手算)
      • 2.4 中缀表达式转前缀表达式(手算)和计算前缀表达式
      • 2.5后缀表达式的计算(机算)
      • 2.6 中缀表达式转后缀表达式(机算)
      • 2.7 中缀表达式的计算(栈实现)
  • 3.矩阵的压缩存储
    • 3.1 对称矩阵的压缩存储
    • 3.2 三角矩阵的压缩存储
    • 3.3 三对角矩阵(带状矩阵)
    • 3.4 稀疏矩阵压缩存储
      • 3.4.1 存储方法一 结构体方式存储
      • 3.4.2 存储方法二 十字链表法

栈的应用

1.栈的括号匹配

问题分析:
问题还是很简单就是,利用栈的特性,左括号进栈,右括号出栈实现匹配,在栈空且所有括号都扫过一遍后结束
在这里插入图片描述

代码实战:

南京理工大学上机题目

苗苗今天刚刚学会使用括号,不过他分不清小括号,中括号,大括号和尖括号,不知道怎么使用这些括号,请帮助他判断括号使用是否正确。

注意:不需要区分括号的优先级。

输入格式
共一行,包含一个由 <,(,{,[,>,),},] 构成的字符串。

输出格式
如果输入的字符串中的括号正确匹配则输出 yes,否则输出 no。

数据范围
输入字符串长度不超过 10000

输入样例:

(){}

输出样例:

yes

问题分析:

  • 想到用栈来实现括号匹配的问题
  • 第一步,肯定是实现栈的基础操作(当然为了简单快捷,选择静态存储的方式实现栈)
    • 栈的定义
    • 栈的初始化
    • 入栈
    • 出栈
    • 判空
  • 具体问题具体分析
    • 写一个括号匹配函数,模拟整个过程
    • 主函数中补上字符串的输入

完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MaxSize 100001
typedef struct{
	char data[MaxSize]; //静态数组存放栈中元素 
	int top;           // 栈顶元素 
}SqStack;

void InitSqStack(SqStack &S)
{
	S.top=-1;
}

bool StackEmpty(SqStack S)
{
	if(S.top==-1)
		return true;
	return false;
}

bool Push(SqStack &S,char x)
{
	S.data[++S.top]=x;
	return true;
}

bool Pop(SqStack &S,char &x)
{
	x=S.data[S.top--];
	return true;
}

bool BracketCheck(char str[])
{
	SqStack S;
	InitSqStack(S);
	for(int i=0;i<strlen(str);i++)    //-1是因为fgets函数读入最后一个字符是/n要去掉 
	{
		if(str[i]=='<'||str[i]=='('||str[i]=='{'||str[i]=='[') //匹配到左括号 
		{
			Push(S,str[i]);
		}
		else                                                   //匹配到右括号 
		{	char x; 
			Pop(S,x);
			if(str[i]=='>'&&x!='<')
				return false;
			if(str[i]==')'&&x!='(')
				return false;
			if(str[i]=='}'&&x!='{')
				return false;
			if(str[i]==']'&&x!='[')
				return false;
		}
	}
	return StackEmpty(S); //检索完全部括号后,栈空说明匹配成功
}
int main()
{
	
	char str[MaxSize];
	fgets(str,MaxSize,stdin);
	// 检查字符串的最后一个字符是否为换行符,并去除它  
    int len = strlen(str);  
    if (len >0&&str[len-1] =='\n') 
	{  
        str[len-1] ='\0';  
    }  
    
	if(BracketCheck(str))
		printf("yes");
	else printf("no");
}

在这里插入图片描述

2.栈的表达式求值

2.1 中缀、后缀、前缀表达式

在学习栈的表达式求值之前 明确的概念

中缀表达式(符号在中间)

a+b
a+b-c

后缀表达式(符号在后边)

ab+
ab+c-

前缀表达式(符号在前边)

+ab
-+abc


引子:为学习计算机机算做铺垫,计算机更喜欢处理后缀表达式这种形式

2.2 中缀表达式改写为后缀表达式(手算)

  • 从左到右的找符号,找到合适的符号就把符号两边的操作数和符号写成后缀表达式的形式
    在这里插入图片描述

2.3 后缀表达式的计算(手算)

  • 从左往右扫描,每遇到一个运算符,就让运算符前面最近的两个操作数执行对应运算,合体为一个操作数
    在这里插入图片描述

从左往右我们发现,最后出现的操作数先被运算,想到栈这种数据结构

2.4 中缀表达式转前缀表达式(手算)和计算前缀表达式

类似于中缀表达式改写为后缀表达式,只是遵循的是右优先原则
在这里插入图片描述
类似于后缀表达式的计算,但是是从右边开始依次入栈,遇到符号出栈…

2.5后缀表达式的计算(机算)

  • 从左到右扫描,
  • 遇到操作数就入栈,遇到符号就将栈顶两个操作数出栈,符号计算完再入栈
  • 直到全部扫描一遍后,若表达式合法,最后栈中只会留下一个结果就是最后结果
    在这里插入图片描述

2.6 中缀表达式转后缀表达式(机算)

  • 遇到操作数,直接加入后缀表达式
  • 遇到界限符,遇到"(“直接入栈,直到遇见”)“,把此时”(“上面的所有运算符都依次出栈加入后缀表达式,注意”(“不加入,”)"也入栈
  • 遇到运算符。依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,若碰到“(”或栈空则停止。之后再把当前运算符入栈。

2.7 中缀表达式的计算(栈实现)

本质就是将中缀表达式转后缀表达式和后缀表达式的计算结合起来

用栈实现中缀表达式的计算:
初始化两个栈,操作数栈和运算符栈若扫描到操作数,压入操作数栈
若扫描到运算符或界限符,则按照“中缀转后缀”相同的逻辑压入运算符栈(期间也会弹出运算符,每当弹出一个运算符时,就需要再弹出两个操作数栈的栈顶元素并执行相应运算,运算结果再压回操作数栈)

在这里插入图片描述

矩阵的压缩存储通过数组的形式来实现

3.矩阵的压缩存储

3.1 对称矩阵的压缩存储

对称矩阵
在这里插入图片描述

在这里插入图片描述

  • 对称矩阵大小存储的大小是多少

(1+n)*n/2

  • 按行优先的原则,ai,j是第几个元素(注意是第几个元素)

先算前面行一共有多少个,再加上当前的列坐标
1+2+3+…(i-1)再+j 个元素即i(i-2)/2+j个元素
如果是下标那就得-1

3.2 三角矩阵的压缩存储

下三角矩阵和上三角矩阵
在这里插入图片描述
压缩存储策略:按行优先原则将橙色区元素存入一维数组中。并在最后一个位置存储常量c
在这里插入图片描述
按行优先的原则,ai,j是第几个元素(注意是第几个元素)跟对称矩阵是一样的,当i<j的时候就是那个常数c,即n(n+1)/2

3.3 三对角矩阵(带状矩阵)

什么是三对角矩阵?
在这里插入图片描述
主对角元素的矩阵,上下左右下标差值不等于1的情况下为0
在这里插入图片描述
按行优先的原则,ai,j是第几个元素

前i-1行共3(i-1)-1个元素
ai,j是i行第j-i+2个元素
ai,j是第2i+j-2个元素
如果数组下标从0开始 k=2i+j-3

若已知数组下标k,如何得到i, j ?

前i-1行共3(i-1)-1个元素
前i行共3i-1个元素
显然,3(i-1)-1 <k+1 ≤ 3i-1
在这里插入图片描述

3.4 稀疏矩阵压缩存储

稀疏矩阵:非零元素远远少于矩阵元素的个数
压缩存储策略:
顺序存储―一三元组<行,列,值>

3.4.1 存储方法一 结构体方式存储

定义一个结构体,存储i,j,v

3.4.2 存储方法二 十字链表法

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

win10+eclipse+ESP8266_RTOS_SDK开发环境构建

官网教程 https://docs.espressif.com/projects/esp8266-rtos-sdk/en/latest/get-started/eclipse-setup.html 1. 导入工程 Build and Flash with Eclipse IDE — ESP8266 RTOS SDK Programming Guide documentation (espressif.com) 导入整个SDK&#xff0c;便于查看所有代…

网络安全 day6 --- 抓包技术HTTPS协议小程序PC应用WEB转发联动

免责声明 本免责声明适用于作者所有文章内容。使用者需明确&#xff0c;网络安全技术仅供学习和合法研究使用&#xff0c;不得用于任何非法活动&#xff0c;如未经授权的入侵、攻击或数据窃取&#xff0c;所有相关法律责任由使用者自行承担。由于网络安全操作可能带来系统崩溃、…

智慧工地数据集-可移动生产要素检测与分割

智慧工地数据集&#xff0c;可移动生产要素检测与分割数据集篇&#xff0c;超高清数据&#xff0c;拍摄于武汉火神山&#xff0c;雷神山医院。包含13种工地中主要移动目标&#xff0c;Bulldozer - 推土机 Concrete mixer - 混凝土搅拌机 Crane - 起重机 Excavator - 挖掘机 Han…

jsp+servlet+mysql机票订票管理系统

jspsevletmysql机票订票管理系统 一、系统介绍二、功能展示1.机票查询2.选择航班3.填写乘客信息4.提交定单 四、其它1.其他系统实现 一、系统介绍 系统主要功能&#xff1a; 机票查询 1.航行类型 2.出发城市 3.到达城市 4.出发日期 5.返回日期 选择航班 1.航班信息 2.起飞时间…

瑞芯微rv1126 Linux 系统,修改系统时区,包有效方法

在 Linux 系统中,修改时区的步骤通常包括创建符号链接到正确的时区文件,并确保相关的配置文件已正确更新。然而,某些系统可能有额外的步骤或需要修改其他配置文件来使更改生效。以下是一些步骤。 1. 创建符号链接 ln -sf /usr/share/zoneinfo/Asia/Hong_Kong /etc/localti…

GitLab邮箱发送邮件:如何实现自动化发信?

gitlab邮箱发送邮件设置教程&#xff1f;Gitlab邮箱配置和使用&#xff1f; GitLab不仅提供了代码版本控制、持续集成/持续部署等功能&#xff0c;还支持通过其内置的邮件功能实现自动化邮件发送。AokSend将深入探讨如何在GitLab中配置和使用邮箱发送邮件功能。 GitLab邮箱发…

如何在 Selenium 中获取网络调用请求?

引言 捕获网络请求对于理解网站的工作方式以及传输的数据至关重要。Selenium 作为一种 Web 自动化工具,可以用于捕获网络请求。本文将讨论如何使用 Selenium 在 Java 中捕获网络请求并从网站检索数据。 我们可以使用浏览器开发者工具轻松捕获网络请求或日志。大多数现代 Web…

react18基础教程系列--安装环境及packagejson文件分析

一个React项目中&#xff0c;默认会安装: react:React框架的核心react-dom:React 视图渲染的核心「基于React构建WebApp(HTML页面)J—>react-native:构建和渲染App的react-scripts: 脚手架为了让项目目录看起来干净一些&#xff0c;把webpack打包的规则及相关的插件/LOADER…

一、链表-算法总结

文章目录 一、链表1.1 提纲1.2 链表删除1.2.1 删除排序链表中的重复元素&#xff08;仅保留一个重复元素&#xff09;1.2.2 删除排序链表中的重复元素 II &#xff08;删除所有重复的元素&#xff09; 1.3 链表反转1.3.1 反转链表1.3.2 反转链表 1.4 合并链表1.4.1 合并两个有序…

图新地球-将地图上大量的地标点批量输出坐标到csv文件【kml转excel】

0.序 有很多用户需要在卫星影像、或者无人机航测影像、倾斜模型上去标记一些地物的位置&#xff08;如电线杆塔、重点单位、下水盖等&#xff09; 标记的位置最终又需要提交坐标文本文件给上级单位或者其他部门使用&#xff0c;甚至需要转为平面直角坐标。 本文的重点是通过of…

第 1 0 章OpenCV

本章概述如何通过 Python 接口使用流行的计算机视觉库 OpenCV。OpenCV 是一个C 库&#xff0c;用于&#xff08;实时&#xff09;处理计算视觉问题。实时处理计算机视觉的 C 库&#xff0c;最初由英特尔公司开发&#xff0c;现由 Willow Garage 维护。OpenCV 是在 BSD 许可下发…

基于深度学习的医学图像分类与诊断系统(开题报告免费领)

深度学习开始大放异彩的工作&#xff0c;莫过于在ImageNet数据集上&#xff0c;对输入图片的分类了。只要输入图片&#xff0c;就能判断图片中主体所属的类别。然而&#xff0c;和分类问题输入图像输出主体的类别不一样&#xff0c;分割问题需要对每个像素点的类别进行识别。下…

Unity实现自己的协程系统(协程有顺序)

你的类可以在不继承Mono的脚本使用协程,但本质仍然需要借助其他Mono对象的Update来调度 实现了一个有执行顺序的协程的调度器&#xff0c;用于在 Unity 中管理多个协程的执行。通过 ICoroutineNodeOrder 和 ICoroutineWaitCondition 两个接口&#xff0c;可以定义每个协程的执行…

labview禁用8080端口

需求背景 最近电脑上安装了labview全家桶,发现idea的8080端口项目启动报错,一直提示8080端口被占用。最简单的办法就是找到8080端口的服务,然后关闭这个服务。但是我不想这么做,我想把labview的web服务器的端口给修改了。 操作教程 1、cmd查看8080端口 2、windows进程 同…

ICM20948 DMP代码详解(17)

接前一篇文章&#xff1a;ICM20948 DMP代码详解&#xff08;16&#xff09; 前一篇文章讲到了inv_icm20948_set_chip_power_state函数中尚需解析的3个函数中的第1个函数&#xff1a;inv_icm20948_write_single_mems_reg_core。并没有完全讲完&#xff0c;本回继续解析。为了便于…

搭建本地DVWA靶场教程 及 靶场使用示例

1. DVWA简介 DVWA&#xff08;Damn Vulnerable Web Application&#xff09;一个用来进行安全脆弱性鉴定的PHP/MySQL Web 应用平台&#xff0c;旨在为网络安全专业人员测试自己的专业技能和工具提供合法的环境&#xff0c;帮助web开发者更好的理解web应用安全防范的过程。 DVW…

利用MR设备实现弹吉他教学:实战案例详解

随着混合现实(Mixed Reality, MR)技术的发展,越来越多的应用开始探索如何将这种沉浸式的体验融入到教育与娱乐中。特别是在音乐教育领域,MR技术为乐器学习提供了全新的可能性。本文将通过分析一个基于Unity开发的吉他教学应用案例,探讨如何利用MR设备,如Oculus Quest或Ap…

Boot中使用Redis缓存

除了RedisTemplate,Spring Cache 还有如下方式 即使不写Repository也可以自动注入 只要extends CrudRepository 最好不要写Repository有可能冲突 自动注入用Autowired或Resource都可

Chainlit集成Langchain并使用通义千问实现和数据库交互的网页对话应用增强扩展(text2sql)

前言 我在上一篇文章中《Chainlit集成Langchain并使用通义千问实现和数据库交互的网页对话应用&#xff08;text2sql&#xff09;》 利用langchain 中create_sql_agent 创建一个数据库代理智能体&#xff0c;但是实测中发现&#xff0c;使用 create_sql_agent 在对话中&#x…

yolo学习 (一) 安装yolov8及训练

随便搞个python环境&#xff0c;直接装或者anaconda都行&#xff0c;python版本最低3.8以上 一、安装yolov8 &#xff08;cpu版本&#xff09; pip install ultralytics yolov8安装版本比较省事&#xff0c;不过这里默认装的是CPU版本 import torch print(torch.__version_…