退役(AFO)???不存在的,自己选的路跪着也要走完
今天上午考了一下往届的初赛题,发现知识点还有很多遗忘与不清楚,特整理如下:
(不要问我为什么在初赛考完后才发……我可能在搞笑)
也不要误以为这是今天的考试题,这是往届的往届的,于此同时纪念一下凉凉的一下午
后缀表达式:
先了解一下中缀表达式吧
就是我们平时用的表达式,符号都在数字中间,这就叫中缀表达式
那么后缀表达式,顾名思义就是符号都放在数字后面
比如: (中缀表达式)
(后缀表达式)
我们先来看看怎么用中缀表达式转化为后缀的
用一个栈来存储符号(栈底自定义一个优先级最小的符号),一个数组来记录转化后的表达式
我们保证栈中的优先级,自底向上是增加的,也就是说栈上方的一定比栈下面的优先级高
现在来扫描原串
遇到一个数字就将其放入数组中
(这个地方有点问题,应该是一连串的数,你总不能把250,分成2 5 0三个来存吧)
遇到一个符号就将其放入栈中,若当前的栈顶的优先级大于现在串里的符号,我们就将其弹出栈,直到遇到一个优先级比它小的,才停止
中缀表达式看成一个字符串,从左到右开始扫描中缀表达式;
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
6.最终将栈中的元素依次出栈,输出。
现在我们再来讨论一下这个转化有什么意义
我们很容易就能理解表达式的数学含义,但是要把表达式丢给计算机去处理,它并不能像人一样有逻辑的去判断先处理哪一步,后处理哪一步,它只会严格的按照从左只有执行,因此为了符合计算机运行方式,必须把原表达式转换为对应的后缀表达式才行。
而且据ldw老师说,这样的模拟题考起来还很不好写,所以还是好好学一下
还有一种叫前缀表达式
其实和后缀差不多,而且用的也不是很多
就直接摘百科了
(1) 首先构造一个运算符栈(也可放置括号),运算符(以括号为分界点)在栈内遵循越往栈顶优先级不降低的原则进行排列。
(2)从右至左扫描中缀表达式,从右边第一个字符开始判断:
如果当前字符是数字,则分析到数字串的结尾并将数字串直接输出。
如果是运算符,则比较优先级。如果当前运算符的优先级大于等于栈顶运算符的优先级(当栈顶是括号时,直接入栈),则将运算符直接入栈;否则将栈顶运算符出栈并输出,直到当前运算符的优先级大于等于栈顶运算符的优先级(当栈顶是括号时,直接入栈),再将当前运算符入栈。
如果是括号,则根据括号的方向进行处理。如果是右括号,则直接入栈;否则,遇左括号前将所有的运算符全部出栈并输出,遇右括号后将左右的两括号一起删除。
(3) 重复上述操作(2)直至扫描结束,将栈内剩余运算符全部出栈并输出,再逆缀输出字符串。中缀表达式也就转换为前缀表达式了。
其实和后缀唯一不一样的就是转化的时候我们从右往左,然后再逆着输出,就好啦
小总结:
中缀表达式: 符号在中间
前缀表达式: 符号在前面
后缀表达式: 符号在后面
来看一道例题吧
快速排序
用习惯了sort函数,居然连快排都忘得差不多了???
不应该啊,快排所用的分治的思想还是蛮重要的
again,again
用我的口水话,乱糊一下,要是哪里有错误,还麻烦各路神仙指教,谢谢Orz
快排:分治
我们的目标:经过多次操作使得原序列有序
实现方法:每次选取一个数,将大于等于这个数的数都放在它右边,小于这个数的数都放在它左边,然后对于左右两个区域再重复这个操作
具体操作:在一个序列中随便选取一个数作为基准数 X
然后从左往右找到一个比X大或等于的数a[i],从右往左找一个小于X的数a[j],如果 i < j 我们就交换
代码
#include
using namespace std;
int a[10];
void quick_sort(int l,int r){
int x=a[l],i=l,j=r;
while(a[i]x) j--;
if(i<=j){
swap(a[i],a[j]);
i++;j--;
}
if(i