Scheme中列表中奇数元素的平方积

Scheme中列表中奇数元素的平方积,scheme,Scheme,我想在Scheme中编写一个代码,将平方奇数元素写入列表。例如(列表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))] [e

我想在Scheme中编写一个代码,将平方奇数元素写入列表。例如(列表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)))]))
对于运行,我编写了这个
(奇数元素平方的乘积(列表1 2 3 4 5))
我得到的错误如下:

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

我应该怎么做才能使这段代码正常运行?谢谢您的回答。

首先,您需要正确设置格式:

(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)))]))
现在,您的代码存在多个问题:

  • 您试图递归地处理序列,但缺少一个终止案例:当您传递空序列时会发生什么?这就是错误的来源:您无法访问空序列的第一个元素

  • 您需要以某种方式建立您的结果:当前,您正在将
    '()
    发送到您的
    cond
    的第一个分支的nirvana中,并在第二个分支的函数调用位置输入一个值

  • 让我们从头开始:

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

    (define (fn seq)
      (if (null? seq)
           ;; termination case
           ;; recursive case
           ))
    
    让我们先来看看递归的例子:您需要计算平方并将其与其余的平方相乘(接下来将计算)

    在终止情况下,您没有平方的值。所以你只需要使用乘法的单位值:
    1


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

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

    (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)))]))
    
    现在,您的代码存在多个问题:

  • 您试图递归地处理序列,但缺少一个终止案例:当您传递空序列时会发生什么?这就是错误的来源:您无法访问空序列的第一个元素

  • 您需要以某种方式建立您的结果:当前,您正在将
    '()
    发送到您的
    cond
    的第一个分支的nirvana中,并在第二个分支的函数调用位置输入一个值

  • 让我们从头开始:

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

    (define (fn seq)
      (if (null? seq)
           ;; termination case
           ;; recursive case
           ))
    
    让我们先来看看递归的例子:您需要计算平方并将其与其余的平方相乘(接下来将计算)

    在终止情况下,您没有平方的值。所以你只需要使用乘法的单位值:
    1


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

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

  • 跳过偶数元素
  • 将每个元素平方
  • 以元素的乘积为例
  • 这样,一个实现自然地使用更简单的函数(大多数函数存在于Scheme中)表示为:


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

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

  • 跳过偶数元素
  • 将每个元素平方
  • 以元素的乘积为例
  • 这样,一个实现自然地使用更简单的函数(大多数函数存在于Scheme中)表示为:

    然后您可以实现一两个helper函数,如
    skip-every-n

    和:

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

    (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))))
    
    与:

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

    (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))))
    

    您的
    cond
    非常混乱,似乎没有意义。Protip:不要试图在一个过程中完成所有事情。在您的情况下,您缺少两个关键步骤1)递归没有终止案例,2)您甚至没有尝试计算乘积。如果这不是一个家庭作业练习,那么有一种非常简单的方法可以通过
    map
    filter
    apply
    实现您所需的结果。您的
    cond
    非常混乱,似乎没有意义。Protip:不要试图在一个过程中完成所有事情。在您的情况下,您缺少两个关键步骤1)递归没有终止案例,2)您甚至没有尝试计算乘积。如果这不是一个家庭作业练习,那么有一个非常简单的方法可以通过
    map
    filter
    apply
    获得您所需的结果。非常好!简单的规则
    compose
    完成了这项工作!很不错的!简单的规则
    compose
    完成了这项工作!