correct some errors in dsa chp4.md.

This commit is contained in:
Shine wOng
2019-05-31 15:42:59 +08:00
parent 17a7b84247
commit a8e4f7f8c6

View File

@@ -103,13 +103,13 @@ bool paren(const char exp[]){
根据上面的描述可以看出,栈混洗只需要满足唯一一个条件:出栈时栈不得为空。只要满足该条件的一个序列都是一个合法的栈混洗。这个和上面描述的括号匹配问题是不是感觉有一点相似啊?其实它们之间本质就是一样的,一个入栈操作可以看做是一个左括号,一个出栈操作可以看做是一个右括号,合法的栈混洗要求入栈操作大于出栈操作,匹配的括号表达式要求左括号数量大于右括号。
可以通过递推表达式或者排列组合的方法来得到栈混洗的数量。关于这个可以参考[栈混洗的数量](https://www.cnblogs.com/jiayouwyhit/p/3222973.html)。从结论上来说,所有的操作数量有$C_{2n}^{n}$个,其中合法的操作数有$C_{2n}^{2-1}$个。
可以通过递推表达式或者排列组合的方法来得到栈混洗的数量。关于这个可以参考[栈混洗的数量](https://www.cnblogs.com/jiayouwyhit/p/3222973.html)。从结论上来说,所有的操作数量有$C_{2n}^{n}$个,其中合法的操作数有$C_{2n}^{n-1}$个。
> 合法栈混洗的快速判断。
经常会有这种问题,给你一个出栈序列,需要你判断它是否是合法的。慢慢模拟吧来的太慢了,没有耐心。所以需要开发出一些快速的方法。
一种方法是出栈序列中元素i之后比其小的元素必须是降序排列的。这是比较容易理解的因为在出栈序列中排列在元素i之后且比i小的元素在元素i出栈时必然已经入栈了并且在元素i出栈时仍然滞留在栈中他们之后的出栈次序当然是递减的。具体可以看[这篇](https://blog.csdn.net/Xiao__Tian__/article/details/51111632)
一种方法是出栈序列中元素i之后比其小的元素必须是降序排列的。这是比较容易理解的因为在出栈序列中排列在元素i之后且比i小的元素在元素i出栈时必然已经入栈了并且在元素i出栈时仍然滞留在栈中他们之后的出栈次序当然是递减的。具体可以看[这篇](https://blog.csdn.net/Xiao__Tian__/article/details/51111632)
另一种方法是我邓公的方法。合法栈混洗的充要条件是它的出栈序列不含`312`模式。这个条件的必要性是显然的,因为`312`是三个元素栈混洗中唯一不合法的那个。但是充分性的证明好像有点复杂,至今不会......
@@ -124,7 +124,7 @@ bool paren(const char exp[]){
问题的实现方面,首先肯定需要一个运算符栈,因此就是它需要延迟缓冲。为了确定各个运算符之间的优先级,还需要建立一个优先级表。这里还要考虑一些特殊的情况:
+ 括号的处理。括号可以强行改变运算符之间的优先级。例如左括号`(`作为新来的运算符时,其优先级高于所有运算符。但作为栈顶的运算符时,其优先级小于所有运算符。而右括号`)`永远不会入栈,其优先级也小于所有运算符,但是等于左括号。
+ 原表达式扫描完毕的处理。往往会有这种情况,即原表达式扫描完毕了,但是栈中还有没有完成计算的运算符。为了处理这种情况,可以将结束符`\0`也添加到优先级表中,它的优先级小于所有其他运算符,直到它遇到为添加到栈底的`\0`,栈空后,计算结束。
+ 原表达式扫描完毕的处理。往往会有这种情况,即原表达式扫描完毕了,但是栈中还有没有完成计算的运算符。为了处理这种情况,可以将结束符`\0`也添加到优先级表中,它的优先级小于所有其他运算符,直到它遇到为添加到栈底的`\0`,栈空后,计算结束。
此外,对于操作数,也需要建立一个操作数栈。因为相关的操作数也需要其对应的运算符获得了运算的权限才能计算,这个栈也是起到延迟缓冲的作用。