【问题标题】:Scheme dot product function of two listsScheme 两个列表的点积函数
【发布时间】:2016-10-19 02:02:00
【问题描述】:

我正在尝试定义一个 dot-prod 函数,该函数将两个列表作为参数,并通过采用 x1*y1+x2*y2 等来应用点积版本。我让它与一个空列表一起工作,但就是这样。谢谢。

    (define (dot-prod l1 l2)
      (cond ((or (null? l1)(null? l2)) '())
            (else
             (cons (* (car l1) (car l2))
                   (* (cdr l1) (cdr l2))))))

【问题讨论】:

    标签: scheme racket


    【解决方案1】:

    这非常适合使用内置程序。假设列表的长度相等:

    (define (dot-prod l1 l2)
      (apply + (map * l1 l2)))
    

    但如果你想从头开始编写解决方案,你必须:

    1. 返回一个对基本情况有意义的值 - 如果是加法,我们需要一个零,而不是一个空列表,我们不会构建一个新列表作为输出
    2. 在递归步骤中调用 dot-prod 过程,您完全忘记了这一点
    3. 有意义地组合结果 - 同样,如果我们要进行加法,我们希望使用 + 而不是 cons

    这就是我的意思:

    (define (dot-prod l1 l2)
      (cond ((null? l1) 0)
            (else
             (+ (* (car l1) (car l2))
                (dot-prod (cdr l1) (cdr l2))))))
    

    无论哪种方式,它都按预期工作:

    (dot-prod '(1 2 3) '(4 5 6))
    => 32
    

    【讨论】:

    • 我会说(foldl + (map * l1 l2)) 比在这里使用apply 更好。
    • 我认为foldl需要三个参数。
    【解决方案2】:

    'for/sum' 循环可以在这里用于一个简单易懂的功能。如果 l 和 k 是 2 个列表:

    (define (dotproduct l k)
      (for/sum ((i l)(j k))
        (* i j)))
    

    测试:

    (dotproduct '(1 2 3) '(4 5 6))
    ; =>32
    

    如果 (x y) 值作为列表列表出现,也可以修改:

    (define (f l)
      (for/sum ((i l))
        (apply * i)))
    
    (f '((1 4)(2 5)(3 6)))
    ; => 32
    

    如果要评估 x、y、z 甚至更多值,该方法也是可扩展的。

    【讨论】:

      猜你喜欢
      • 2015-12-16
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 2012-02-18
      • 1970-01-01
      • 1970-01-01
      • 2015-01-08
      相关资源
      最近更新 更多