Scheme 在球拍中创建求值函数

Scheme 在球拍中创建求值函数,scheme,racket,Scheme,Racket,函数应执行的操作示例: (列表34697)←→ 3x^4+4x^3+6x^2+9x+7 到目前为止,我所拥有的: (define (poly-eval x numlist) (compute-poly-tail x numlist 0 0)) (define (compute-poly-tail xn list n acc) (cond [(null? list) acc] [else (compute-poly-tail (first list) (rest li

函数应执行的操作示例: (列表34697)←→ 3x^4+4x^3+6x^2+9x+7

到目前为止,我所拥有的:

(define (poly-eval x numlist)
(compute-poly-tail x numlist 0 0))

(define (compute-poly-tail xn list n acc)
    (cond
      [(null? list) acc]
    [else (compute-poly-tail (first list) (rest list)
                       (+ acc (* (first list) (expt xn n))) (+ n 1))]))



(check-expect(poly-eval 5 (list 1 0 -1)) 24)
(check-expect(poly-eval 0 (list 3 4 6 9 7)) 7)
(check-expect(poly-eval 2 (list 1 1 0 1 1 0))  54)
预期成果:

(check-expect(poly-eval 5(list 1 0 -1)) 24)
(check-expect(poly-eval  0 (list 3 4 6 9 7))7)
(check-expect(poly-eval 2 (list 1 1 0 1 1 0)) 54)

我得到一个运行时错误。有人能看出我做错了什么吗。我不知道为什么会得到这些结果。

构建功率系数和未知列表,然后使用map函数

; 2*3^1+4*3^0
; input is 3 and '(2 4)
; we need '(3 3) '(2 4) '(1 0)
; use map expt build '(3^1 3^0)
; use map * build '(2*3^1 4*3^0)
; use foldr + 0 sum up

(define (poly-eval x coefficient-ls)
  (local ((define power-ls (reverse (build-list (length coefficient-ls) values)))
          (define unknown-ls (build-list (length coefficient-ls) (λ (i) x))))
    (foldr + 0 (map * coefficient-ls (map expt unknown-ls power-ls)))))



构建功率系数和未知列表,而不是使用map函数

; 2*3^1+4*3^0
; input is 3 and '(2 4)
; we need '(3 3) '(2 4) '(1 0)
; use map expt build '(3^1 3^0)
; use map * build '(2*3^1 4*3^0)
; use foldr + 0 sum up

(define (poly-eval x coefficient-ls)
  (local ((define power-ls (reverse (build-list (length coefficient-ls) values)))
          (define unknown-ls (build-list (length coefficient-ls) (λ (i) x))))
    (foldr + 0 (map * coefficient-ls (map expt unknown-ls power-ls)))))



代码中有几个错误:

  • 您需要按照正确的顺序处理系数列表,对应于它们在多项式中的位置!您可以:
    • 从头开始反转列表,并从右到左(更简单)处理系数
    • 或者在
      (sub1(length numlist))
      中开始
      n
      ,并在每次迭代时减少它(这就是我所做的)
  • compute poly tail
    中调用递归时,参数的顺序和值不正确,请检查过程定义,确保按照定义的顺序传递值,并且第一次调用
    (第一个列表)
    没有任何意义
  • 不应命名
    列表
    参数,这将与同名的内置过程冲突。我把它重命名为
    lst
这将解决以下问题:

(define (poly-eval x numlist)
  (compute-poly-tail x numlist (sub1 (length numlist)) 0))

(define (compute-poly-tail xn lst n acc)
  (cond
    [(null? lst) acc]
    [else (compute-poly-tail xn
                             (rest lst)
                             (- n 1)
                             (+ acc (* (first lst) (expt xn n))))]))
它按预期工作:

(poly-eval 5 (list 1 0 -1))
=> 24

(poly-eval 0 (list 3 4 6 9 7))
=> 7

(poly-eval 2 (list 1 1 0 1 1 0))
=> 54

代码中有几个错误:

  • 您需要按照正确的顺序处理系数列表,对应于它们在多项式中的位置!您可以:
    • 从头开始反转列表,并从右到左(更简单)处理系数
    • 或者在
      (sub1(length numlist))
      中开始
      n
      ,并在每次迭代时减少它(这就是我所做的)
  • compute poly tail
    中调用递归时,参数的顺序和值不正确,请检查过程定义,确保按照定义的顺序传递值,并且第一次调用
    (第一个列表)
    没有任何意义
  • 不应命名
    列表
    参数,这将与同名的内置过程冲突。我把它重命名为
    lst
这将解决以下问题:

(define (poly-eval x numlist)
  (compute-poly-tail x numlist (sub1 (length numlist)) 0))

(define (compute-poly-tail xn lst n acc)
  (cond
    [(null? lst) acc]
    [else (compute-poly-tail xn
                             (rest lst)
                             (- n 1)
                             (+ acc (* (first lst) (expt xn n))))]))
它按预期工作:

(poly-eval 5 (list 1 0 -1))
=> 24

(poly-eval 0 (list 3 4 6 9 7))
=> 7

(poly-eval 2 (list 1 1 0 1 1 0))
=> 54

我不明白
xn
参数在做什么。它开始时是
x
,因此我希望它始终保持与
x
相同的值,但是在递归调用中它得到
(第一个列表)
。那么接下来的术语怎么还知道
x
是什么呢?接下来我不明白的是
n
n
以零开始,但对于先有最重要项的多项式,我希望
n
以多项式的次数开始,就像
x^2+2*x+1
一样,我希望
n
2
开始,在每次递归调用中按1向下,然后你把
acc
作为最后一个参数,所以我猜
(+acc…)
表达式也应该这样,因为最后一个参数是递归调用,我不明白
xn
参数在做什么。它开始时是
x
,因此我希望它始终保持与
x
相同的值,但是在递归调用中它得到
(第一个列表)
。那么接下来的术语怎么还知道
x
是什么呢?接下来我不明白的是
n
n
以零开始,但对于先有最重要项的多项式,我希望
n
以多项式的次数开始,就像
x^2+2*x+1
一样,我希望
n
2
开始,在每个递归调用上按1向下,然后你把
acc
作为最后一个参数,所以我猜
(+acc…)
表达式也应该这样,因为最后一个参数是递归调用Hello oscar,如果我想使用第二个选项,从n开始(sub1(length numlist))并在每次迭代时减小它,我该怎么做呢。我很困惑。@loren我可以帮你,但这不是取消“接受”复选标记的理由,那只是粗鲁。对不起,我很抱歉奥斯卡不会再这样做了。顺便说一句,你帮了大忙。:)您好,oscar,如果我想使用第二个选项,从n开始(sub1(length numlist)),并在每次迭代时减少它,我该怎么做呢。我很困惑。@loren我可以帮你,但这不是取消“接受”复选标记的理由,那只是粗鲁。对不起,我很抱歉奥斯卡不会再这样做了。顺便说一句,你帮了大忙。:)