【问题标题】:printing pairs from a list in scheme从方案中的列表中打印对
【发布时间】:2023-03-30 06:20:01
【问题描述】:

我正在尝试从一个列表中打印对,有点像方案中的一个子集,但有两个元素,就像这样

(1 2 3 4 5)

((1 2) (1 3) (1 4) (1 5) (2 3) (2 4) (2 5) (3 4) (3 5) (4 5))

我写的代码不行

(define (subset x) 
(if ( null? x) x
    (map cons x (subset (cdr x)))))

这只是返回一个空列表

【问题讨论】:

    标签: scheme lisp racket mit-scheme


    【解决方案1】:

    我更喜欢显式编写 lambda,这样更容易理解传递的参数:

    (define subset
        (lambda (lst)
            (if (null? lst)
                lst
                (append (map (lambda (el) (cons (car lst) el)) (cdr lst))
                        (subset (cdr lst)))
            )))
    

    (subset '(1 2 3 4 5))
    => ((1 . 2) (1 . 3) (1 . 4) (1 . 5) (2 . 3) (2 . 4) (2 . 5) (3 . 4) (3 . 5) (4 . 5))
    

    编辑:以下关于地图的解释仅在某些版本的方案中有效,请阅读 Sylwester 对此答案的评论。

    map 遍历提供给它的 n 个列表,并将proc 应用于列表中相同位置的 n 个元素。这意味着它可以应用proc 的次数不超过最短列表的长度,但你一直给它一个空列表(从最后一次递归调用向后)。

    (顺便说一句,这是scheme

    【讨论】:

    • 您关于map 的信息不准确。根据 R5RS 和 R6RS,如果map 有多个列表参数,则它们必须具有相同的长度。 SRFI-1 按照您描述的方式工作,R7RS-small 似乎也采用了它,尽管目前还没有很多实现支持 R7RS。
    • @Sylwester 感谢您的评论,我将编辑我的答案。我认为在调试 OP 的代码时就是这种情况。
    【解决方案2】:

    #lang racket 中这很容易,因为我们有combinations

    (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
    

    【讨论】:

      【解决方案3】:

      如果项目的顺序也很重要,可以使用以下:

      (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)))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-03
        • 2022-01-09
        • 1970-01-01
        • 2023-01-11
        • 1970-01-01
        • 1970-01-01
        • 2018-10-23
        • 1970-01-01
        相关资源
        最近更新 更多