Scheme中列表中奇数元素的正方形乘积

时间:2015-06-19 11:39:21

标签: scheme

我想在Scheme中编写一个代码,用于写入list中的square奇数元素。例如(list 1 2 3 4 5)这个列表应该写225.为此,我编写了这段代码:

(define (square x)(* x x))

(define (product-of-square-of-odd-elements sequence)
  (cond[(odd? (car sequence)) '() (product-of-square-of-odd-elements (cdr sequence))]
       [else ((square (car sequence)) (product-of-square-of-odd-elements (cdr sequence)))]))

对于跑步我写这个(product-of-square-of-odd-elements (list 1 2 3 4 5)) 我得到这样的错误:

car: contract violation
  expected: pair?
  given: '()

如何使此代码正常运行?谢谢你的回答。

3 个答案:

答案 0 :(得分:2)

首先,您需要进行适当的格式化:

(define (square x) (* x x))

(define (product-of-square-of-odd-elements sequence)
  (cond
    [(odd? (car sequence))
     '() (product-of-square-of-odd-elements (cdr sequence))]
    [else
     ((square (car sequence)) (product-of-square-of-odd-elements (cdr sequence)))]))

现在您的代码存在多个问题:

  1. 您正在尝试以递归方式处理序列,但您错过了终止案例:当您传递'() - 空序列时会发生什么?这是您的错误的来源:您无法访问空序列的第一个元素。

  2. 你需要以某种方式建立你的结果:目前你在'()的第一个分支中发送cond进入必杀技,并将值放入函数调用位置第二个。

  3. 所以让我们从头开始:

    您以递归方式处理序列,因此需要处理两种情况:

    (define (fn seq)
      (if (null? seq)
           ;; termination case
           ;; recursive case
           ))
    

    首先考虑递归情况:你需要计算平方并将其乘以其余的正方形(你接下来要计算)。

    (* (if (odd? (car seq)
             (square (car seq))
             1)
       (fn (cdr seq)))
    

    在终止案例中,你没有任何价值。所以你只需使用乘法的单位值:1

    这不是一个好的解决方案,因为您可以将其转换为尾递归形式,并使用更高阶函数来完全抽象递归。但我认为这对于一个开始就足够了。

答案 1 :(得分:1)

您可以将问题分解为,例如:

  1. 跳过偶数元素
  2. 对每个元素进行平方
  3. 采取元素的产物
  4. 有了这个,实现自然地使用更简单的函数(大多数存在于Scheme中)表示为:

    (define product-of-square-of-odd-elements (l)
      (reduce * 1 (map square (skip-every-n 1 l))))
    

    然后实现一两个辅助函数,如skip-every-n

答案 2 :(得分:1)

使用transducers

(define prod-square-odds
  (let ((prod-square-odds 
         ((compose (filtering odd?)
                   (mapping square)) *)))    
    (lambda (lst)
      (foldl prod-square-odds 1 lst))))


(prod-square-odds '(1 2 3 4 5))
; ==> 225

它使用可重复使用的传感器:

(define (mapping procedure)
  (lambda (kons)
    (lambda (e acc)      
      (kons (procedure e) acc))))

(define (filtering predicate?)
  (lambda (kons)
    (lambda (e acc)
      (if (predicate? e)
          (kons e acc)
          acc))))