从scheme中的列表打印对
我试着从一个列表中打印对,有点像scheme中的子集,但有两个元素,就像这样 (12345) ((12)(13)(14)(15)(23)(24)(25)(34)(35)(45)) 我写的代码不起作用从scheme中的列表打印对,scheme,lisp,racket,mit-scheme,Scheme,Lisp,Racket,Mit Scheme,我试着从一个列表中打印对,有点像scheme中的子集,但有两个元素,就像这样 (12345) ((12)(13)(14)(15)(23)(24)(25)(34)(35)(45)) 我写的代码不起作用 (define (subset x) (if ( null? x) x (map cons x (subset (cdr x))))) 这只需返回#lang racket中的空列表,这非常简单,因为我们有组合: (combinations '(1 2 3 4 5) 2) ; ==>
(define (subset x)
(if ( null? x) x
(map cons x (subset (cdr x)))))
这只需返回#lang racket
中的空列表,这非常简单,因为我们有组合
:
(combinations '(1 2 3 4 5) 2)
; ==> ((1 2) (1 3) (2 3) (1 4) (2 4) (3 4) (1 5) (2 5) (3 5) (4 5))
现在这不打印任何内容。要将其打印到终端,您可以使用displayln
:
(displayln (combinations '(1 2 3 4 5) 2))
; ==> #<void>, ((1 2) (1 3) (2 3) (1 4) (2 4) (3 4) (1 5) (2 5) (3 5) (4 5)) printed to terminal as side effect
(displayln(组合)(12345)2))
; ==> #, (12)(13)(23)(14)(24)(34)(15)(25)(35)(45)(45))作为副作用打印到终端
我更喜欢显式编写lambda,这样更容易理解传递的参数:
(define subset
(lambda (lst)
(if (null? lst)
lst
(append (map (lambda (el) (cons (car lst) el)) (cdr lst))
(subset (cdr lst)))
)))
编辑:下面关于map的解释仅在scheme的某些版本中有效,请阅读Sylvester对该答案的评论 遍历提供给它的n个列表,并将
proc
应用于列表中相同位置的n个元素。这意味着它可以应用proc
的次数不超过最短列表的长度,但您会一直给它一个空列表(从上一次递归调用开始)
(顺便说一句,这是普通的
方案
)如果项目顺序也很重要,可以使用以下方法:
(define (subsets l)
(let loop ((n 0) ; run a loop for each item
(ol '())) ; start with blank output list
(cond
[(= n (length l)) (reverse ol)] ; output ol when last item reached;
[else
(let* ((x (list-ref l n)) ; get one item
(jl (for/list ((i l) ; get remaining list
(j (in-naturals))
#:unless (= j n))
i))
(kl (for/list ((i jl)) ; make combinations with each of remaining list
(list x i))))
(loop (add1 n) (cons kl ol)))])))
测试:
(subsets '(1 2 3 4 5))
输出:
'(((1 2) (1 3) (1 4) (1 5))
((2 1) (2 3) (2 4) (2 5))
((3 1) (3 2) (3 4) (3 5))
((4 1) (4 2) (4 3) (4 5))
((5 1) (5 2) (5 3) (5 4)))
有关
map
的信息不准确。根据R5RS和R6RS,如果映射到的列表参数多于一个,则它们必须具有相同的长度。按照您描述的方式工作,R7RS small似乎也采用了它,尽管还没有多少实现支持R7RS。@Sylvester感谢您的评论,我将编辑我的答案。我想在调试OP的代码时就是这样。
'(((1 2) (1 3) (1 4) (1 5))
((2 1) (2 3) (2 4) (2 5))
((3 1) (3 2) (3 4) (3 5))
((4 1) (4 2) (4 3) (4 5))
((5 1) (5 2) (5 3) (5 4)))