这个问题一个特点--麻烦!
如何检查结构呢,结构错误是因为不符合我们的目标要求。
在这里我们需要一个格式正确的表达式序列,那么我们就得视具体情况而作出判断。在这里可是涉及一个巨大的数学思想的!!!其实比较简单,就是我们高中数学里面最常用到的”分类讨论“。
如果你有一个缜密的思路,在这里是非常好的,我这里的分析估计疏漏了大量的情况,希望大家能够一起补充,共同进步。
首先是比较简单的一部分,括号数量以及对应情况是否正确。
那么到底什么是正确的对应呢?类似于这种的()表达式,那么我们现在简化我们的表达式,假设就只有括号,这可以通过简单的字符串处理获得。看以下几种情况:
((()))
()(())
(()()(()))
我们不难发现都是正确的,那么究竟为什么正确呢?因为每一个‘(’都有一个‘)’与之相对应。那让我们对这些对应一个个解析
( ( () ) )
() ( () )
( () () ( () ) )
从颜色我们可以看出,一旦出现‘)’就会与最近的一个‘(’相互配对,我们假设配对以后她们一起消失了,那么后面的‘)’与前面的变化效果是一致的。这样一来,我们就可以得出一个判断方法:如果出现‘)’就立刻与前面的‘(’配对,然后一起消失,如果没有可以配对的就自动留下。直到最后,如果还剩下一些括号,就说明匹配有错误。那么这种处理方法要求我们要利用另外一个线性空间保留以前的括号,并且能够更新(就是比对--匹配--消失)。这时我们容易想到用一个数组(足够长,以便存放所有的数据),并且用一个整数P指向(其实就是记录)已经使用的数组(因为我们是线性扫描的,所以在一步一步输入括号串的时候是逐步向这个数组里面添加数据的)末尾,有新数据进入,就和末尾的数据匹配对比,如果匹配就一起消失(即那个整数P减少一个单位)。如此工作,直至最后。那么我们继续剖析这个数组,我们可以发现这个数组只在末端处理数据,就像一个饼干袋子,我们吃放都是在一边进行的(如果有人吃饼干,袋子两边都开的话,招呼一声--还有人跟我一样--不过我是饼干吃了一半以后再开另外一边);还有一种形象的比喻是,使用的时候模式就是彈夹的模式。其实这种结构就是那个所谓的栈数据结构。
我们定义push(object) 将object压入栈中,pop()弹出栈顶元素,作为返回值.
n: = 1
repeat
c : = expression[n]
if c = ' ) ' then
d : = pop()
if not d = ' ( ' then
push(d)
push(c)
n: = n + 1
until n > length[expression]
return stack
以上是操纵的伪代码,这里需要注意,我们用两个线性空间存储数据(一个是存储所有的待扫描括号,另外一个是用来模拟栈操作的)。
关于stack的具体实现可以查看相关文档,JAVA里面有这个类大家可以直接用。
然后就是一些繁琐的分类情况了
a.操作符(包括+-*/^)不能两个一起连续出现
b.类似于 '('+'操作符' 不能出现(到后面我们是允许减号出现的,因为它可以被理解为负号)
这些东西很繁琐,写文章的时候我在进一步完善这一部分。
好了以上就是结构的检查部分了。
在这里我们学习了一种数据结构--栈。关于栈的详细讨论任何一本数据结构书中都有详细说明,大家自己去查阅。
在这里提一个问题:现在有2n+1个数字,其中我们知道有一个数字它出现的次数>=n+1,我们希望通过一次扫描来源数据来找出这个数字,有什么办法可以解决呢?Please use the stack.It can help you solve this problem.