我试图实现使用一个简单的Java Lisp表达式求值。 实际上,有丰富的关于这个问题的信息,但现在看来,他们都使用两个独立的堆栈以结果到达。 我不知道是否有可能实现只使用一个堆栈,什么一些伪代码可能看起来像这样的程序。
谢谢。
对于什么我谈论更多信息请参考
- http://www.chegg.com/homework-help/questions-and-answers/outline-given-import-javautil-public-class-simplelispexpressionevaluator-current-input-lis-q2332957
- http://stdioe.blogspot.ca/2012/01/lets-implement-simple-lisp-interpreter.html
无论你链接的解释,使一个非常重要的假设:+, - ,*,等都是二元函数,也就是说,它们始终正好用两个参数。 在实际Lisp中,可以说(+ 1 2 3 4 5)
总结一串数字。 但是,如果你愿意接受简化假设每个运营商的元数是已知的,那么你绝对可以只用一个堆栈做到这一点。 关键:转栈倒挂。
口译员您链接到有这样的堆栈:
底- > ( + ( - 2 1 ) 4 )
< -顶(推我们从这里弹出)
但是,你也可以阅读你的表情向后,从右边,并建立堆栈是这样的:
顶- > ( + ( - 2 1 ) 4 )
< -底
然后,你基本上得到RPN,逆波兰式。 RPN发挥真的很好用栈。
该算法是这样的:
- 如果你看到一个括号,忽略它
- 如果你看到一个操作数,将其推入堆栈
- 如果你看到一个运营商,调用它。 操作员关闭弹出许多值,因为它需要,然后推动其结果到堆栈
举个例子来说, ( + ( - 2 1 ) 4 )
以下是如何算法将工作:
堆栈: 空 阅读: )
操作:括号忽略。 左: ( + ( - 2 1 ) 4
堆栈: 空 阅读: 4
操作:操作压入堆栈。 左: ( + ( - 2 1 )
堆栈:4 阅读: )
操作:括号忽略。 左: ( + ( - 2 1
堆栈:4 阅读: 1
操作:操作压入堆栈。 左: ( + ( - 2
堆栈:1 4 读: 2
操作:操作数压入堆栈。 左: ( + ( -
堆栈:2 1 4 阅读: -
操作:操作者调用。 它会弹出2和1从堆栈,然后按2-1=1
到其上。 左: ( + (
堆栈:1个4 阅读: (
行动:括号忽略左: ( +
堆栈:1个4 阅读: +
动作:操作者调用。 它会弹出1和4从堆栈,然后按1+4=5
到其上。 左: (
堆栈:5 阅读: (
行动:括号忽略左: 无
完成! 结果是5,符合市场预期。
PS约忽略括号。 这将很好地工作,只要您输入的表达式是良好的,但它可以形成非共良好表现,并给予他们荒谬的价值观。 例如(+ - + 1 2 3 4)
被解释为(+ (- (+ 1 2) 3) 4)
如果你想阻止这种行为,只需按下右括号到堆栈中。 当谈到时间来调用操作,爆开的参数,加上一个额外的令牌。 确保令牌是一个近距离的括号,否则抛出一个错误 。 一旦你有一个结果,把它压入堆栈。 请确保您在阅读的下一个标记是一个开放的括号,然后将其丢弃 。
PPS此,如果像在真实的Lisp中,函数的参数本身也可以是功能都变得复杂多了。 然后,你没有操作员/操作数之间的区别得心应手该RPN依赖,你需要更加注重括号作为分组元素。 我不知道,如果你可以做一个全面的Lisp表达式求值,具有可变参数数量和功能,如式操作数,只有一个堆。