波兰(Poland)是个了不起的国家。元素周期表中的放射性元素钋(Po),是居里夫人发现的,是以她的祖国波兰命名的。在计算机科学中常用到的波兰表达式(Polish Notation)、逆波兰表达式(Reverse Polish Notation)也是以波兰命名的。中国也是个了不起的国家,我知道的中国剩余定理(Chinese remainder theorem)是以中国冠名的。其他以中国冠名的物件有中国结、中国龙(Chinese Dragon)、中国梦、中国模式、中国特色的社会主义等。嗯,今天不说中国,主要说波兰。
波兰逻辑学家扬·武卡谢维奇(Jan Lukasiewicz)在1924年发明了波兰表达式,用于简化命题逻辑,后来波兰表达式也用于算数(Arighmatic)和代数(Algebra)。通常的表达式叫中缀表达式,这种表达式运算符(operator)在操作数(operand)的中间。例如表达式1 + 2的运算符+位于操作数1和2的中间。波兰表达式也叫前缀表达式,这种表达式运算符在操作数的前面。中缀表达式1 + 2对应的前缀表达式是+ 1 2。
好好的中缀表达式不用,用什么前缀表达式?
运算符是有优先级的。例如中缀表达式1+2×3要先算乘法后算加法。如果我们要先算加法后算乘法,那通常我们需要加括号改变运算顺序。例如(1+2)×3。而如果用前缀表达式,在运算符的参数个数(arity)已知的情况下,我们可以省略括号。例如前缀表达式×+ 1 2 3对应中缀表达式为(1+2)×3。前缀表达式在Lisp计算机语言中有广泛的应用。
逆波兰表达式是计算机科学家F. L. Bauer和E. W. Dijkstra在20世纪60年代各自独立发明的。逆波兰表达式也叫后缀表达式,这种表达式运算符在操作数的后面。中缀表达式1 + 2对应的后缀表达式是1 2 +。不太严格地说,后缀表达式基本上是前缀表达式反过来。后缀表达式具有前缀表达式的好处,即不需要括号来改变运算顺序。另外的好处就是很容易用一个栈(Last In First Out)的数据结构实现从左到右一次扫描来计算表达式的值。(如果前缀表达式,要从右往左扫描,不顺手吧)后缀表达式在Forth、PostScript等计算机语言中有广泛的应用。
下面是采用栈计算后缀表达式3 2 + 4 -的步骤(对应中缀表达式为3 + 2 - 4),左边是栈底,右边是栈顶。
3
3 2
3 2 +
5
5 4
5 4 -
1
同时我觉得后缀表达式可能比较适合用来实现中文编程。英文句子的单词都用空格分开,英文中的符号很丰富,圆括号、方括号、花括号等应有尽有,所以英文编程语言使用这些符号很自然。而中文中这些符号都是后来加的,古文中甚至句逗都没有。所以我觉得自然的中文编程语言应该越少使用符号越好。另外中文中的倒装用法本来也很多,倒装和逆波兰表达式有神似之处。比如中文的“吾谁与归”指“吾与谁归”,“走你”指“你走”等。
下面是使用处于试验阶段的微型亲密数编程语言采用后缀表达式来计算3 + 2 - 4的过程。“和”用来分开数字。“加”和“减”是+和-运算符。每个步骤输出的结果都保存在栈中。
欢迎试用亲密数语言!
亲> 三和二
三和二
亲> 加
五
亲> 和四
五和四
亲> 减
一
亲>
这里要说一下,逆波兰表达式的发明者F. L. Bauer是德国人,E. W. Dijkstra是荷兰人,他们的发明和波兰表达式相反,叫逆波兰表达式,没有叫德国或荷兰表达式。波兰表达式的发明者扬·武卡谢维奇发明了一个实际赚到了俩。我爷爷愿意供子女读书,他的理论是穷要读书(现在丑也要读书),富要养猪。他还有个理论是,供出一个大学生相当于供出俩。因为供出一个大学生还会再娶(嫁)一个大学生。这当然是基于他老人家对就业和找对象都比较乐观的前提得出的结论。
参考资料
[1] http://en.wikipedia.org/wiki/Polish_notation
[2] http://en.wikipedia.org/wiki/Reverse_Polish_notation