从scheme中的列表打印对

从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) ; ==>

我试着从一个列表中打印对,有点像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)
; ==> ((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)))