[英]Solve a polynomial for a given value x in scheme
I am passing a list of pairs which represent a polynomial and a value of 'x.'我正在传递一个代表多项式和“x”值的对列表。 I need to write a Scheme function which evaluates the polynomial at x.我需要编写一个方案 function 来评估 x 处的多项式。
i.e ('((1 . 3) (1 . 2) (1 . 1) (1 . 0)) = x^3 + x^2 + x + 1
This is what I have so far:这是我到目前为止所拥有的:
(define (eval-poly p x)
(+
(* (car (car p)) x x x)
(* (car (car (cdr p))) x x)
(* (car (car (car (car p)))) x)
(car (car (car (car (cdr p)))))
))
The lines (+ (* (car (car p)) xxx)
and (* (car (car (cdr p))) xx)
access and evaluate the first two pairs correctly, but I am unsure how to access the last two pairs in the list and evaluate them. (+ (* (car (car p)) xxx)
和(* (car (car (cdr p))) xx)
行正确访问和评估前两对,但我不确定如何访问最后两对在列表中并评估它们。
The first place OP code has gone astray is in the use of cdr
. OP 代码误入歧途的第一个地方是使用cdr
。 When in doubt about use of car
and cdr
, jump into the REPL and enter some test expressions to gain clarity.当对car
和cdr
的使用有疑问时,跳到 REPL 并输入一些测试表达式以获得清晰性。 Given OP example polynomial p
, OP solution would work if corrected:给定 OP 示例多项式p
,如果更正,OP 解决方案将起作用:
;; Given p = '((1 . 3) (1 . 2) (1 . 1) (1 . 0))
(car p) => '(1 . 3)
(car (car p)) => 1
(cdr p) => '((1 . 2) (1 . 1) (1 . 0))
(car (cdr p)) => '(1 . 2)
(car (car (cdr p))) => 1
(cdr (cdr p)) => '((1 . 1) (1 . 0))
(car (cdr (cdr p))) => '(1 . 1)
(car (car (cdr (cdr p)))) => 1
(cdr (cdr (cdr p))) => '((1 . 0))
(car (cdr (cdr (cdr p)))) => '(1 . 0)
(car (car (cdr (cdr (cdr p))))) => 1
So, changing a few car
s to cdr
s will be a step in the right direction:因此,将一些car
更改为cdr
将是朝着正确方向迈出的一步:
(define (eval-poly p x)
(+
(* (car (car p)) x x x)
(* (car (car (cdr p))) x x)
(* (car (car (cdr (cdr p)))) x)
(car (car (cdr (cdr (cdr p)))))))
This definition will work for OP example polynomial, but has deficiencies;此定义适用于 OP 示例多项式,但有不足之处; it will only work for third degree polynomials where all terms are explicitly included.它仅适用于明确包含所有项的三次多项式。 The OP approach will not work in general; OP 方法一般不会起作用; these cases would fail:这些情况将失败:
;; p = '((2 . 3) (1 . 1))
;;
;; p = '((1 . 2) (2 . 1) (3 . 0))
;;
;; p = '((3 . 5) (2 . 3) (-1 . 1) (3 . 0))
A better implementation would take advantage of the fact that the representation of the polynomial captures the degree of each term in the cdr
of the term.更好的实现将利用多项式的表示捕获项的cdr
中每个项的度数这一事实。 Also, a better implementation should not require a specific number of terms in the polynomial representation.此外,更好的实现不应该要求多项式表示中有特定数量的项。 We could achieve this by writing a procedure that evaluates a term, and mapping it over the polynomial.我们可以通过编写一个评估项的过程并将其映射到多项式上来实现这一点。
(define (eval-term t x)
(let ((coeff (car t))
(deg (cdr t)))
(* coeff (expt x deg))))
(define (eval-poly p x)
(apply + (map (lambda (t) (eval-term t x)) p)))
Here a lambda
expression is used to create a procedure that takes only a term t
as its argument;这里使用了一个lambda
表达式来创建一个仅以术语t
作为参数的过程; that procedure is mapped over the polynomial, and apply
is used to sum the results together.该过程被映射到多项式上,并且apply
用于将结果相加。 If eval-term
is not needed elsewhere, it may be cleaner to define this inside of eval-poly
:如果在其他地方不需要eval-term
,在eval-poly
内部定义它可能更清晰:
(define (eval-poly p x)
(define (eval-term t)
(let ((coeff (car t))
(deg (cdr t)))
(* coeff (expt x deg))))
(apply + (map eval-term p)))
This new definition will work for polynomials other than third degree, as well as for polynomials with omitted terms:这个新定义将适用于除三次以外的多项式,以及省略项的多项式:
> (eval-poly '((1 . 3) (1 . 2) (1 . 1) (1 . 0)) 2)
15
> (eval-poly '((2 . 3) (1 . 1)) 2)
18
> (eval-poly '((1 . 2) (2 . 1) (3 . 0)) 2)
11
> (eval-poly '((3 . 5) (2 . 3) (-1 . 1) (3 . 0)) 2)
113
The obvious way to do this is with a syntactically-recursive function:显而易见的方法是使用语法递归 function:
Given a current value:给定当前值:
car
of the specification tells you to do to the value and process the cdr
.否则,将规范的car
告诉您对值执行的任何操作添加并处理cdr
。This is very natural in Scheme:这在 Scheme 中很自然:
(define (eval-poly p x)
;; evaluate p on x
(define (eval-poly/loop pt v)
;; evaluate pt on x with a current value of v
(if (null? pt) ;we're done
v
(eval-poly/loop ;we're not done
(cdr pt)
(+ v (* (expt x (cdr (car pt)))
(car (car pt)))))))
(eval-poly/loop p 0)) ;initially the current value is 0
In a language with pattern matching this is possibly even more natural.在具有模式匹配的语言中,这可能更加自然。 This example is Racket:这个例子是球拍:
(define (eval-poly p x)
(define/match (eval-poly/loop pt v)
(('() cv) cv)
(((cons (cons power coeff) ptt) cv)
(eval-poly/loop
ptt
(+ cv (* (expt x power) coeff))))
((_ _)
(error 'eval-poly "bad poly specification ~S" p)))
(eval-poly/loop p 0))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.