目录
1号方案:0号元素弃之不用,另外还需定义一个length来存放串的长度编辑
2号方案:使用0号元素,并另外定义一个length来存放串的长度。
3号方案:使用0号元素,不使用length,而是使用“\0”来表示串的结尾
前言
昨晚着凉,今天感冒,状态不佳,忙着刷题,还有毕设,没看多少,明天加油。
今天复习了一些队列与栈的应用,以及字符串的相关知识,觉得还是挺有收获的。
一、栈的应用
1、在波兰表达式中的使用
1、什么是波兰表达式
波兰表达式也称为前缀表达式,逆波兰表达式也称为后缀表达式。我们通常的表达式写法被称为中缀表达式。
表达式 | 描述 | 结果 |
---|---|---|
前缀表达式 | 不含括号的的算数表达式,将运算符写在前面,操作数写在后面 | * + 1 2 + 3 4 |
中缀表达式 | 必须含括号,操作符处于操作数的中间 | ( 1 + 2 ) * ( 3 + 4 ) |
后缀表达式 | 不含括号,运算符放在两个运算对象的后面。 | 1 2 + 3 4 + * |
2、用法一:实现中缀转后缀
首先初始化一个栈,用于保存暂时还不能确定运算顺序的运算符。
其次,遍历中缀表达式,其中元素共有三种情况:
1、遇到操作数。直接加入后缀表达式中。
2、遇到界限符。遇到“(”直接入栈;遇到“)”则依次弹出栈内运算符并加入后缀表达式中,直到弹出“(”为止(注:“()”不加入后缀表达式)
3、遇到运算符。依次弹出栈内优先级高于或等于当前运算符的所有运算符,并加入后缀表达式中。若碰上“(”或栈空则停止。再将当前运算符入栈。
最后,将栈内剩余运算符依次弹出,并加入后缀表达式。
3、用法二:实现后缀表达式的运算
首先初始化一个栈,用于存放数据元素。
遍历后缀表达式,若遇上操作数,则入栈;若遇上操作符,则从栈中出栈两个元素,运算后将结果入栈。
最后栈顶元素就是最终结果。
4、用法三:实现中缀表达式的运算
首先初始化两个栈,一个是操作数栈,一个是运算符栈
其次遍历中缀表达式:
1、若遇到操作数,则将其压入操作数栈
2、若扫描到界限符与运算符,参考中缀转后缀的逻辑,将其压入运算符栈中。
3、若在此期间有运算符被出栈,则每出栈一个运算符,就出栈两个操作数,并将其与该运算符进行相应运算,运算结果再压回栈中。
最后,操作数栈中的栈顶元素就是最终结果
二、队列的应用
1、树的层次遍历
明后天可能会复习到
2、图的广度优先遍历
过几天会复习到
3、队列在操作系统中的应用
多个进程争抢使用有限的系统资源时,FCFS(先来先服务)是常用的策略
三、串
串就是字符串,也是一个非常重要的内容。个人觉得主要体现在<string.h>中自带了许多的函数,能非常方便地使用字符串;还有一点就是字符串的操作不是一个数据元素一个数据元素的进行操作,多数情况下都是对一个子串进行操作。
1、串的基本概念
1、定义
串,即字符串(String)是由零个或多个字符组成的有限序列
字符个数n称为串的长度,n=0时的串称为空串
注:有的语言用双引号(如Java、C),有的用单引号(如python)
2、术语
子串:串中任意个连续的字符组成的子序列
主串:包含子串的串
字符在主串中的位置:字符在串中的序号(即位序,从1开始数)
子串在主串中的位置:子串的第一个字符在主串中的位置(即位序,从1开始数)
3、串的基本操作
如增删改查等通常以子串为操作对象
重点是Index定位操作,以及StrCompare比较操作
2、串的顺序存储
结构体的定义与初始化和顺序表一样,只是ElemType默认为char。
由于串中的字符的位置就是位序,所以是从1号开始标号的,因此为了方便操作,会让串的0号位为空,从1号位开始使用。
这样就有四种方案可供选择。
1号方案:0号元素弃之不用,另外还需定义一个length来存放串的长度
2号方案:使用0号元素,并另外定义一个length来存放串的长度。
3号方案:使用0号元素,不使用length,而是使用“\0”来表示串的结尾
由于没有表示长度的变量,所以当需要频繁求串长时,非常不方便
4号方案:0号元素存放串的长度。
由于一个char大小是8bit,所以数据范围为0~255,所以只能存放长度不超过255的串
3、串的链式存储
与链表一样,不过由于指针是4Byte,而char是1Byte,所以若一个节点仅存放一个字符,则存储密度非常低。因此可以考虑一个节点存储多个字符,这样就能有效增加存储密度。
四、模式匹配算法
字符串模式匹配:在主串中找到与模式串相同的子串,并返回其所在位置
模式串:需要寻找的串,不一定能在主串中找到
子串:串中任意个连续的字符组成的子序列
例:主串:“afgdsgadfahdsfhjgjwbjf”
模式串:“adfa”,返回7
模式串:“q”,返回找不到
1、朴素匹配(暴力解)
顾名思义,暴力解,双循环。若主串长n,模式串长m,时间复杂度最坏情况下为O(nm)
2、KMP算法
原理我是懂了,但是获取next数组的函数不会写,暂时搁置,有空再说。next数组就是记录了模式串中各个子串的前后缀中最大公共子串的位置。
KMP算是朴素匹配的优化。当朴素匹配时,若是模式串1~m-1位全都匹配上了,就只有第m位没有匹配上,此时不需要从模式串头开始匹配,而是根据next数组选择从哪开始匹配。
计算next的时间复杂度为O(m),匹配的时间复杂度为O(n),加在一起的时间复杂度就是O(m+n)
总结
栈与队列用处很多,它们算是抽象出来的最基础的数据结构之一,在生活中也处处体现着栈与队列。
明天可能会休息一下,但是还是得看一些树的相关内容。