按长度对列表列表进行排序
sort list of lists by length
我正在完成一个 Scheme 教程,该教程要求使用排序进行练习,“按列表的长度按降序排序。”我自己写了这个解决方案:
(define (ls-len-sort ls)
(sort ls (lambda (x y) (> (length x) (length y)))))
但是当我测试它时,我并没有得到我期望的结果:
> (ls-len-sort '('(1) '(3 3 3) '(5 5 5 5 5) '(4 4 4 4) '(2 2)))
'('(1) '(3 3 3) '(5 5 5 5 5) '(4 4 4 4) '(2 2))
我预计 '('(5 5 5 5 5) '(4 4 4 4) '(3 3 3) '(2 2) '(1))
。
排序有效,比较列表长度有效。
> (sort '(1 3 5 4 2) >)
'(5 4 3 2 1)
> (sort '(1 3 5 4 2) (lambda (x y) (< (abs (sin x)) (abs (sin y)))))
'(3 4 1 2 5)
> (> (length '(2 2)) (length '(3 3 3)))
#f
> (> (length '(4 4 4 4)) (length '(3 3 3)))
#t
但是对元素为列表的列表进行排序不会:
> (sort '('(1) '(3 3 3) '(5 5 5 5 5) '(4 4 4 4) '(2 2)) (lambda (x y) (> (length x) (length y))))
'('(1) '(3 3 3) '(5 5 5 5 5) '(4 4 4 4) '(2 2))
我在教程里查了正确答案,和我写的一样,一模一样:
(define (sort-length ls)
(sort ls (lambda (x y) (> (length x) (length y)))))
所以我猜这可能是 Racket v8.4 [cs] 与本教程所针对的 MIT-Scheme (R5RS) 版本之间的区别?
你得到这个结果是因为 quote
. Quote isn't just different name for function list
的错误使用,它是不评估其参数和 returns 的形式。比较这两个例子:
> (list 1 2 3 (+ 2 2) 5)
(1 2 3 4 5)
> '(1 2 3 (+ 2 2) 5)
(1 2 3 (+ 2 2) 5)
有时结果是一样的:
> (list 1 2 3 4 5)
(1 2 3 4 5)
> '(1 2 3 4 5)
(1 2 3 4 5)
当一个列表被引用时,里面的所有对象也被引用,所以你不必引用它们两次。如您所见,结果完全不同:
> '('(1) '(3 3 3) '(5 5 5 5 5) '(4 4 4 4) '(2 2))
('(1) '(3 3 3) '(5 5 5 5 5) '(4 4 4 4) '(2 2))
> '((1) (3 3 3) (5 5 5 5 5) (4 4 4 4) (2 2))
((1) (3 3 3) (5 5 5 5 5) (4 4 4 4) (2 2))
您想要哪种变体?您可以将这两个与使用 list
:
创建的列表进行比较
> (list (list 1) (list 3 3 3) (list 5 5 5 5 5) (list 4 4 4 4) (list 2 2))
((1) (3 3 3) (5 5 5 5 5) (4 4 4 4) (2 2))
当您使用正确的变体时,sort 将起作用:
(define (ls-len-sort ls)
(sort ls < #:key length))
> (ls-len-sort '((1) (3 3 3) (5 5 5 5 5) (4 4 4 4) (2 2)))
((1) (2 2) (3 3 3) (4 4 4 4) (5 5 5 5 5))
我正在完成一个 Scheme 教程,该教程要求使用排序进行练习,“按列表的长度按降序排序。”我自己写了这个解决方案:
(define (ls-len-sort ls)
(sort ls (lambda (x y) (> (length x) (length y)))))
但是当我测试它时,我并没有得到我期望的结果:
> (ls-len-sort '('(1) '(3 3 3) '(5 5 5 5 5) '(4 4 4 4) '(2 2)))
'('(1) '(3 3 3) '(5 5 5 5 5) '(4 4 4 4) '(2 2))
我预计 '('(5 5 5 5 5) '(4 4 4 4) '(3 3 3) '(2 2) '(1))
。
排序有效,比较列表长度有效。
> (sort '(1 3 5 4 2) >)
'(5 4 3 2 1)
> (sort '(1 3 5 4 2) (lambda (x y) (< (abs (sin x)) (abs (sin y)))))
'(3 4 1 2 5)
> (> (length '(2 2)) (length '(3 3 3)))
#f
> (> (length '(4 4 4 4)) (length '(3 3 3)))
#t
但是对元素为列表的列表进行排序不会:
> (sort '('(1) '(3 3 3) '(5 5 5 5 5) '(4 4 4 4) '(2 2)) (lambda (x y) (> (length x) (length y))))
'('(1) '(3 3 3) '(5 5 5 5 5) '(4 4 4 4) '(2 2))
我在教程里查了正确答案,和我写的一样,一模一样:
(define (sort-length ls)
(sort ls (lambda (x y) (> (length x) (length y)))))
所以我猜这可能是 Racket v8.4 [cs] 与本教程所针对的 MIT-Scheme (R5RS) 版本之间的区别?
你得到这个结果是因为 quote
. Quote isn't just different name for function list
的错误使用,它是不评估其参数和 returns 的形式。比较这两个例子:
> (list 1 2 3 (+ 2 2) 5)
(1 2 3 4 5)
> '(1 2 3 (+ 2 2) 5)
(1 2 3 (+ 2 2) 5)
有时结果是一样的:
> (list 1 2 3 4 5)
(1 2 3 4 5)
> '(1 2 3 4 5)
(1 2 3 4 5)
当一个列表被引用时,里面的所有对象也被引用,所以你不必引用它们两次。如您所见,结果完全不同:
> '('(1) '(3 3 3) '(5 5 5 5 5) '(4 4 4 4) '(2 2))
('(1) '(3 3 3) '(5 5 5 5 5) '(4 4 4 4) '(2 2))
> '((1) (3 3 3) (5 5 5 5 5) (4 4 4 4) (2 2))
((1) (3 3 3) (5 5 5 5 5) (4 4 4 4) (2 2))
您想要哪种变体?您可以将这两个与使用 list
:
> (list (list 1) (list 3 3 3) (list 5 5 5 5 5) (list 4 4 4 4) (list 2 2))
((1) (3 3 3) (5 5 5 5 5) (4 4 4 4) (2 2))
当您使用正确的变体时,sort 将起作用:
(define (ls-len-sort ls)
(sort ls < #:key length))
> (ls-len-sort '((1) (3 3 3) (5 5 5 5 5) (4 4 4 4) (2 2)))
((1) (2 2) (3 3 3) (4 4 4 4) (5 5 5 5 5))