摘要:在《4个程序员的一天》一文中,idior问道: 不知道类似foo(+,-,+,*,/, a) //a is a array实现a[0]+a[1]+a[2]*a[3]/a[4]这种功能能实现吗?(用FP) 昨晚去看了看scheme的数据结构操作,得出以下解法:(;号后面是注释)(define (inner-runner 1st-number operators numbers)  (if (= 0 (length operators))    1st-number    (inner-runner ((car operators) 1st-number (car numbers))   ; calculate new 1st-number                          (cdr operators)                                            ; get new operators list                          (cdr numbers))))                                          ; get new numbers list (define (Foo operators numbers)  (inner-runner (car opes) ops (cdr opes))) 然后我们来run run试试:3 * 5 - 2 + 4  = 17> (Foo (list * - + ) (list 3 5 2 4))等于17 ,得解 ;) 好了,现在来说下解题的思路:Setp1:从Numbers中“POP”出第一个数作为初始化操作数,叫做1st-number,。Numbers现在剩下n个数字,我们称这个新的list为Numbers*. Setp2:然后递归的分别从Operators和Numbers*里“POP”出运算符和第二个运算数,拿来和前面我们拿到的1st-number做运算,把得到的结果当作新的1st-number,连同新的Operators和新的Numbers*,重复step2,直到Operators变为空。 这时候再回过头来看上面的scheme代码: 先简单说明下scheme的语法:(list * - + ) :构造一个list,包含3个元素:*,-, +(length operators):得到operators这个list的长度 (car operators):得到operators这个list的第一个元素。例:(car (list 1 2 3)) = 1,注意它返回的是一个元素,不是list (cdr operators):得到operators这个list从第二个元素开始的子list例:(cdr (list 1 2 3)) = (list 2 3),注意它返回的是个子list而不是元素 来看看inner-runner函数,它完成的是step2的工作:它先看看operators是否为空,如果为空就直接返回1st-number;如果不是,那么分别取得一个operator和一个number,进行(operator 1st-number number)运算,把得到的结果又当作1st-number,连同剩下的operators和numbers进行下一轮的递归。 至于主函数foo就比较简单了。它接受2个list类型的参数:Operators,包含n个运算符,Numbers,包含n+1个数字(当然你也可以放多于n+1的数字,不过多的数不会参与运算),Foo做的工作只是取出最初的1st-number,剩下的就交给inner-runner搞定了。 至于预算步骤,让我们来看看(先减少些运算符以缩小运算过程):(Foo (list * - )......[阅读全文]