我已经尝试了很多次,但我仍然坚持这个问题,这是我的输入:
(define *graph*
'((a . 2) (b . 2) (c . 1) (e . 1) (f . 1)))
我希望输出如下:((2 a b)(1 c e f))
这是我的代码:
(define group-by-degree
(lambda (out-degree)
(if (null? (car (cdr out-degree)))
'done
(if (equal? (cdr (car out-degree)) (cdr (car (cdr out-degree))))
(list (cdr (car out-degree)) (append (car (car out-degree))))
(group-by-degree (cdr out-degree))))))
你可以告诉我我的错误是因为我的代码输出是(2 a)。然后我认为我的代码的想法是正确的。
请帮忙!!!
答案 0 :(得分:2)
解决此问题的一种非常好而优雅的方法是使用哈希表来跟踪列表中找到的对。通过这种方式,我们只需要在输入列表上进行一次传递:
(define (group-by-degree lst)
(hash->list
(foldl (lambda (key ht)
(hash-update
ht
(cdr key)
(lambda (x) (cons (car key) x))
'()))
'#hash()
lst)))
结果将以与问题中显示的顺序不同的顺序出现,但仍然是正确的:
(group-by-degree *graph*)
=> '((1 f e c) (2 b a))
如果输出列表中的顺序有问题,请尝试相反,它的效率低于上一个答案,但输出与问题中的输出相同:
(define (group-by-degree lst)
(reverse
(hash->list
(foldr (lambda (key ht)
(hash-update
ht
(cdr key)
(lambda (x) (cons (car key) x))
'()))
'#hash()
lst))))
(group-by-degree *graph*)
=> '((2 a b) (1 c e f))
答案 1 :(得分:-1)
我不知道为什么lambda是必要的;您可以直接定义具有(define (function arg1 arg2 ...) ...)
的功能
然而,除此之外,简单地说,问题是汽车和司机都搞砸了。我找不到一种方法来调整你的解决方案,但这是一个有效的实现:
; appends first element of pair into a sublist whose first element
; matches the second of the pair
(define (my-append new lst) ; new is a pair
(if (null? lst)
(list (list (cdr new) (car new)))
(if (equal? (car (car lst)) (cdr new))
(list (append (car lst) (list (car new))))
(append (list (car lst)) (my-append new (cdr lst)))
)
)
)
; parses through a list of pairs and appends them into the list
; according to my-append
(define (my-combine ind)
(if (null? ind)
'()
(my-append (car ind) (my-combine (cdr ind))))
)
; just a wrapper for my-combine, which evaluates the list backwards
; this sets the order right
(define (group-by-degree out-degree)
(my-combine (reverse out-degree)))