有没有办法将-
(减号)函数更改为+
(加号)函数?
我的作业是在Macluaurin系列上实现罪计算
sin(x) = x-(x^3/3!)+(x^5/5!) -(x^7/7!)+(x^9/9!)-...
每篇文章都有不同的标志。这是我的Lisp代码
(defun sinMac (x series n plusminus)
(cond ((= series 0) 0)
(t (funcall plusminus
(/ (power x n) (factorial n))
(sinMac x (- series 1) (+ n 2) plusminus)))))
是否可以更改plusminus
以兑换标志?如果我得到'+
函数发送'-
到下一个递归调用。通过该电话(获得'-
),我致电'+
,依此类推......
答案 0 :(得分:4)
你可以用圆形列表来做。像这样:
(defun sin-mac (x series n plus-minus)
(cond ((zerop series) 0)
(t (funcall (car plus-minus)
(/ (power x n) (factorial n))
(sin-mac x (1- series) (+ n 2) (cdr plus-minus))))))
(sin-mac x series 1 '#0=(+ - . #0#))
甚至更好,使用labels
包装初始参数:
(defun sin-mac (x series)
(labels ((recur (series n plus-minus)
(cond ((zerop series) 0)
(t (funcall (car plus-minus)
(/ (power x n) (factorial n))
(recur (1- series) (+ n 2) (cdr plus-minus)))))))
(recur series 1 '#0=(+ - . #0#))))
答案 1 :(得分:3)
如果函数是符号,这很容易:
(defun next-function (function)
(ecase function
(+ '-)
(- '+)))
(defun sinMac (x series n plusminus)
(cond ((= series 0) 0)
(t (funcall plusminus
(/ (power x n) (factorial n))
(sinMac x
(- series 1)
(+ n 2)
(next-function plusminus))))))
答案 2 :(得分:1)
我不会交换功能而只是交换标志。使用循环对我来说似乎也更清楚(尽管仍有很多优化机会,但最有可能更有效率):
(defun maclaurin-sinus (x n)
"Calculates the sinus of x by the Maclaurin series of n elements."
(loop :for i :below n
:for sign := 1 :then (- sign)
:sum (let ((f (1+ (* 2 i))))
(* sign
(/ (expt x f)
(factorial f))))))
一些优化使这大约快10倍(使用 n = 5 进行测试):
(defun maclaurin-sinus-optimized (x n)
"Calculates the sinus of x by the Maclaurin series of n elements."
(declare (integer n))
(loop :repeat n
:for j :from 0 :by 2
:for k :from 1 :by 2
:for sign := 1 :then (- sign)
:for e := x :then (* e x x)
:for f := 1 :then (* f j k)
:sum (/ e f sign)))