主题:【原创】将24进行到底 -- 泰让
首先说一下总体上的思路。其实很多朋友已经看出,如果想穷尽4张牌的所有可能的计算,需要找到一个排列方法,能够不遗漏的列举每个算式。运算的数好办,因为它们都只严格的出现1次,问题是对于运算符,简单的插入三个运算符在四个数的空隙中是不行的,因为要是我们加入括号改变运算顺序,其结果也就不同了。但是如果我们要考虑所有插入括号的方式,虽然仍然是可行,但问题就变的相当复杂了。
好在算术表达式不仅仅有常见的中缀法,还有后缀法,或者称为逆波兰法(RPN)。这种方法先写两个参加运算的部分(可以是数,或者小一极的表达式)。简单的说就是原本用1+2来表示的运算,写成rpn就是1 2+,再比如说我们用中缀表示的算式(4-4/7)*7用后缀可以表示成4 4 7 / - 7 *。注意我们这里假定运算数间有可分辨的分隔,这样4 ,4 ,7三个数不至于同四百四十七混淆。
这样表示有什么好处?第一:这么写以后可以不用括号表达所有算式,而如果我们把一个数看作一位,一个运算符也看作1位的话,这个表达式长度总是7位。第二:这样写后计算过程简单。对于有括号的四则运算的解析和运算其实是相当复杂的问题,编译原理中会有一章专门讲这个问题。对于RPN计算就简单很多,我们可以很机械的执行以下步骤:遇到运算数则压栈,如果遇到运算符则将栈顶两运算数进行相应操作。最后如果RPN没有语法错误的话,栈应该只剩下一个数,就是结果。
回到原本的问题,我们现在要做的就是生成所有可能的RPN,然后运算之,检查它是否结果是24。如果我们用1到4代表输入的4张牌点,5到8代表加减乘除四种运算的话,问题就变成了我们如何生成一个7个数的组合,满足以下条件:
1:一到四出现1次且仅出现一次
2:五到八可以重复出现,也可以不出现
3:在任何时候,一到四出现的总数,比五到八出现的次数多(这一条是保证生成的是合乎语法的RPN)
生成了一个组合后,再用上面说的计算方法来算出结果,检查下是否是目标就可以了。当然注意运算过程中别发生除零的错误。
- 相关回复 上下关系8
😄发我一份呀 泰让 字30 2007-03-09 21:45:43
🙂哈,你们论剑的时候别忘了俺! 面壁 字91 2007-03-10 11:38:58
😄那就贻笑大方了。 Highway 字4074 2007-03-09 22:04:41
🙂【注释之1】总体原理
🙂【注释之2】程序实现 3 泰让 字1086 2007-03-06 21:40:27
🙂还是烦请老兄再添点儿注解。。。 面壁 字151 2007-03-06 16:27:36
😄谢谢老弟的捧场。 1 Highway 字281 2007-03-06 08:42:13
🙂交换律和结合律 东方射日 字148 2007-03-06 09:37:26