方案列表压缩列表

时间:2012-09-13 20:02:25

标签: recursion scheme

如果我的输入是一个列表列表,那么我想输出一个包含输入元素的列表,这样它们就像一副扑克牌一样被洗牌。

例如,如果输入为'((1 2 3)(4 5)),那么我希望输出显示为'(1 4 2 5 3)。

我的想法是先从列表中的第一个列表中删除一个元素,然后将列表列表移到列表的后面。这样,就可以追加下一个列表列表的第一个元素。

到目前为止,这是我的代码:

(define (shuffle ls)
   (if (null? ls) '()
       (cond ((null? car (ls)) (append (cdr (ls)) (list (cdr(car(ls)))))))
             (else (car (car (ls)))
                   (append (cdr (ls)) (list (cdr (car (ls))))
                   (shuffle (cdr (ls)))))))

2 个答案:

答案 0 :(得分:1)

[此处的所有代码段都需要先加载SRFI 1。]

您似乎想要的是压缩列表:

> (zip '(1 2 3) '(4 5))
((1 4) (2 5))

但是,正如您所看到的,当它到达最短列表的末尾时会停止。也许你可以编写一个自定义zip,它会在所有元素都耗尽后停止:

(define (my-zip l1 l2)
  (cond ((and (null? l1) (null? l2)) '())
        ((null? l1) (cons (car l2) (my-zip l1 (cdr l2))))
        ((null? l2) (cons (car l1) (my-zip (cdr l1) l2)))
        (else (cons* (car l1) (car l2) (my-zip (cdr l1) (cdr l2))))))

让我们试一试!

> (my-zip '(1 2 3) '(4 5))
(1 4 2 5 3)
> (my-zip '(1 2 3) '(4 5 6 7))
(1 4 2 5 3 6 7)

答案 1 :(得分:0)

这也会起作用...我使用鸡计划所以我必须从srfi-1“导入”过滤器。

(use srfi-1)
(define *deck* '((1 2 3 4) (5 6 7) (9 10 11 12)))

(define nullcar? 
  (lambda (x) 
    (if (not (null? x)) 
      (null? (car x)))))

(define nullcdr? 
  (lambda (x) 
    (if (not (null? x)) 
      (null? (cdr x)))))

(define notnulls 
  (lambda (x) 
    (filter (lambda (e) 
              (not (null? e))) 
            x)))

(define firsts 
  (lambda (l) 
    (if (not (null? l)) 
      (map (lambda (x) 
             (if (not (null? x)) 
               (car x) 
               '())) 
            l))))

(define shuf 
  (lambda (d) 
    (notnulls 
      (append (firsts d) 
              (if (not (nullcar? d)) 
                (if (not (nullcdr? d))  
                  (shuf (map cdr (notnulls d))) 
                  '()) 
               '())))))

喝彩!