嗨,我正在尝试编写一个程序,给定列表列表检查它们是否大小相等,如果它们返回#t.
那么例如,如果我要写(列表计数器?'((1 2 3)(4 5 6)(7 8 9)))程序将返回#t,和(list-counter?'((1 2) 3)(4 5 6)(7 8)))将返回#f.
到目前为止,这就是我所做的:
(define list-counter?
(lambda (x)
(if (list? x)
(if (list?(car x))
(let (l (length (car x))))
(if (equal? l (length(car x))))
(list-counter?(cdr x))
) ) ) ) )
Run Code Online (Sandbox Code Playgroud)
在我将l的长度设置为第一个列表的长度之后,我想我错了.任何帮助,将不胜感激.
有几种方法可以解决这个问题。例如,手动并逐步进行:
(define (all-lengths lists)
(if (null? lists)
'()
(cons (length (car lists))
(all-lengths (cdr lists)))))
(define (all-equal? head lengths)
(if (null? lengths)
true
(and (= head (car lengths))
(all-equal? head (cdr lengths)))))
(define (list-counter? lists)
(let ((lengths (all-lengths lists)))
(all-equal? (car lengths) (cdr lengths))))
Run Code Online (Sandbox Code Playgroud)
让我解释一下上述过程。我将问题分为两步,首先创建一个新列表,其中包含每个子列表的长度 - 这就是所做的all-lengths。然后,将列表中的第一个元素与其余元素进行比较,看看它们是否都相等 - 就是这样all-equal?。最后,list-counter?将其全部包装在一起,使用正确的参数调用前面的两个过程。
或者甚至更简单(更短),通过使用列表过程(高阶过程):
(define (list-counter? lists)
(apply = (map length lists)))
Run Code Online (Sandbox Code Playgroud)
为了理解第二种解决方案,请观察它all-lengths并all-equal?代表更一般过程的特殊情况。当我们需要创建一个新列表并将过程应用于另一个列表的每个元素的结果时,我们使用map. 当我们需要同时将过程(=在本例中)应用于列表的所有元素时,我们使用. 这正是第二个版本正在做的事情。applylist-counter?