比较两个列表,如果它们不相等则返回 false [英] Compare two lists and return false if they are not equal scheme

查看:54
本文介绍了比较两个列表,如果它们不相等则返回 false的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想请你帮忙完成下面的代码,条件是测试列表 wsvs 是否不相等.如果它们不相等,则返回文本 false(#f) 否则处理下面的代码.我盯着满足变量 len1 和 len2 来计算两个列表的长度.当我运行它时,我收到此错误:lambda: no expression after a sequence of internal definition in: lambda 我做错了什么?

i would like to ask you for help to complete code below with condition which is testing if lists ws and vs are not equal. If they are not equal so return text false(#f) else process code below. I stared with fulfilling variables len1 and len2 which are counting length of both lists. When i run it i am getting this error: lambda: no expression after a sequence of internal definitions in: lambda What i am doing wrong?

(define (weighted-sum . ws)
  (define (sub . vs)
    (let ((len1 (length ws)) (len2 (length vs)))
    (if (not (equal? (len1 len2) '#f))
    (foldl
     (lambda (i j res) (+ res (* i j)))
     0
     ws vs)))
   sub)

感谢您的帮助.

推荐答案

length 在 Scheme 中几乎总是一种反模式.

length is almost always an anti-pattern in Scheme.

length 是一个 O(n) 操作,调用两次,然后你调用另一个 O(n) 操作,foldl,导致 weighted-sumO(3n) 过程 - 远非理想的最小值 O(n).foldl 是许多线性计算的不错候选者,但由于长度匹配要求,您创建了一些方钉在圆孔中的情况.

length is a O(n) operation, which is called twice, then you call another O(n) operation, foldl, resulting in a O(3n) process for weighted-sum - far from the ideal minimum O(n). foldl is a nice candidate for many linear computations, but because of the length-matching requirement, you've created a bit of a square-peg-in-a-round-hole situation.

使用named-letmatch*,我们将weighted-sum 写成O(n) 计算 -

Using a named-let and match*, we write weighted-sum as a O(n) computation -

#lang racket

(define ((weighted-sum . ws) . vs) ;; curried form syntactic sugar 
  (let loop ((acc 0)
             (ws ws)
             (vs vs))
    (match* (ws vs)
      ;; both lists have at least one value
      [((list w ws ...) (list v vs ...))
       (loop (+ acc (* w v))
             ws
             vs)]
      ;; both lists are empty
      [((list) (list))
       acc]
      ;; any other case
      [(_ _)
       #f])))

当然 match* 是一个非常漂亮的宏,所以我将向您展示如何使用简单的 cond 重写 weighted-sum表达.准备好逻辑推理帽:条件子句的顺序在这里非常重要 -

Of course match* is a pretty fancy macro, so I'll show you how to rewrite weighted-sum using a simple cond expression. Get your logical reasoning hat ready: the order of the condition clauses is very important here -

(define ((weighted-sum . ws) . vs)
  (let loop ((acc 0)
             (ws ws)
             (vs vs))
    (cond
      ;; both lists are empty
      [(and (null? ws)
            (null? vs))
       acc]
      ;; at least one list is empty
      [(or (null? ws)
           (null? vs))
       #f]
      ;; inductive: both lists have at least one value
      [else
       (loop (+ acc (* (car ws)
                       (car vs)))
             (cdr ws)
             (cdr vs))])))

两个程序有相同的输出 -

Both programs have the same output -

((weighted-sum 1 2 3) 1 2 3)
;; 14

((weighted-sum 1 2 3) 1 2)
;; #f

((weighted-sum 1 2) 1 2 3)
;; #f

((weighted-sum))
;; 0

这篇关于比较两个列表,如果它们不相等则返回 false的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆