Scheme 中的二次公式

Quadratic formula in Scheme

方案

我想定义一个函数 returns 二次公式的根,给定 ax^2+bx+c=0。 Return 只有真正的根源。该列表将 有 0 个、1 个或两个唯一根。

(define (quadratic a b c)
    (cond
        ((> (- (* b b) (* 4 (* a c ) ) ) 0 ) (list ( / ( - (sqrt ( - (* b b) (* (* 4 a) c))) b ) ( * 2 a) )
            ( / ( - ( - (sqrt ( - (* b b) (* (* 4 a) c)))) b ) ( * 2 a) ) ) )
        ((= (- (* b b) (* 4 (* a c ) ) ) 0 ) list( / ( - (sqrt ( - (* b b) (* (* 4 a) c))) b ) ( * 2 a) ))
        (else ('( )'))
    )
)

我得到了

error: unexpected right parenthesis [read]
       #{&read-error}
       #{&i/o-port-error #{input-port #{input-channel "standard input" 0}}}

有没有更好的办法解决?

您有括号问题(显然,这就是错误状态)- 例如,您忘记在代码中打开第二个 list 左侧的一个。这应该可以解决它:

(define (quadratic a b c)
  (cond
    ((> (- (* b b) (* 4 (* a c))) 0)
     (list (/ (- (sqrt (- (* b b) (* (* 4 a) c))) b) (* 2 a))
           (/ (- (- (sqrt (- (* b b) (* (* 4 a) c)))) b) (* 2 a))))
    ((= (- (* b b) (* 4 (* a c))) 0)
     (list (/ (- (sqrt (- (* b b) (* (* 4 a) c))) b) (* 2 a))))
    (else '())))

另外,请注意缩进代码的正确方法 - 它会帮助您发现这样的错误;一个好的编辑器也会很有用。让我们测试程序:

(quadratic 1 -3 -4)
=> '(4 -1)
(quadratic 9 12 4)
=> '(-2/3)
(quadratic 3 4 2)
=> '()

前面的解决方案正确回答了您的问题。但请注意,您的算法会多次执行相同的计算,即使在没有必要的情况下(当行列式为零时),而且代码很难阅读。所以我建议重写你的函数,以更有效地产生相同的结果,更重要的是,以更易读的方式:

(define (quadratic a b c)
  (let ((determinant (- (* b b) (* 4 a c))))
    (if (negative? determinant)
        '()
        (let ((a2 (+ a a)))
          (if (zero? determinant)
              (list (/ (- b) a2))
              (let ((root (sqrt determinant)))
                (list (/ (- root b) a2)
                      (/ (- (- root) b) a2))))))))