Racket / Scheme中的zip功能

时间:2014-02-10 22:08:39

标签: recursion functional-programming scheme lisp racket

给定两个列表,返回一个列表,其元素是大小为2的列表,这样对于i列表,第一个元素是第一个元素i - 元素原始列表,第二个元素是第二个原始列表的i - 元素。如果一个列表小于另一个列表,则结果列表的大小最小;因此,如果其中一个列表为空,则返回一个空列表。例如:

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

> (zip '(1 2 3) '())
'()
> (zip '() '(4 5 6))
'()
> (zip '(8 9) '(3 2 1 4))
'((8 3) (9 2))
> (zip '(8 9 1 2) '(3 4))
'((8 3) (9 4))

6 个答案:

答案 0 :(得分:8)

尝试:

(map cons '(1 2 3) '(a b c))

左右:

(map list '(1 2 3) '(a b c))
(define zip (lambda (l1 l2) (map list l1 l2)))

->(zip '(1 2 3) '(x y z))
'((1 x) (2 y) (3 z))

答案 1 :(得分:3)

因为您没有发布您编写的代码,我猜这是作业。我会给你一些开始的提示,这是解决方案的一般结构,填补空白 - 如果你用自己的方式得到正确的答案会更有趣!

(define (zip lst1 lst2)
  (cond ((<???> lst1)  ; if the first list is empty
         <???>)        ; then return the empty list 
        ((<???> lst2)  ; if the second list is empty
         <???>)        ; then also return the empty list 
        (else          ; otherwise
         (cons (list   ; cons a list with two elements:
                <???>  ; the first from the first list
                <???>) ; and the first from the second list
               (zip <???> <???>))))) ; advance recursion over both lists

我使用样本输入测试了上述实现,结果如预期:

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

(zip '(1 2 3) '())
=> '()

(zip '() '(4 5 6))
=> '()

(zip '(8 9) '(3 2 1 4))
=> '((8 3) (9 2))

(zip '(8 9 1 2) '(3 4))
=> '((8 3) (9 4))

答案 2 :(得分:1)

如果你已经解决了第一个元素的问题,那么你可以递归到列表的其余部分:

(define (zip l1 l2)
  (if (or (null? l1) (null? l2))
      '()
      (cons (list (car l1) (car l2))
            (zip  (cdr l1) (cdr l2)))))

如果您处理列表为空的基本情况。

> (zip '(1 2 3 4) '(a b))
((1 a) (2 b))
> (zip '() '(a b))
()

答案 3 :(得分:0)

如果你的地图实现在最短的列表中停止,那么可以使用zip,Scheme的list参数和apply来定义map。这是一个提示:

(define (zip . lsts)
  (apply <??> <??> lsts))

RSFI-1map就足够了。所以在Racket中添加(require (only-in srfi/1 map))

答案 4 :(得分:0)

如果我们接受了Racket函数,并且放宽了返回2元组的要求,而选择了更为通用的zip,那么我会查看for/list。以下是压缩或交错两个或三个列表的示例,在最短列表中停止

(define l1 '(a b c))
(define l2 '(1 2 3))
(define l3 '(true false))

;; → '((a 1 true) (b 2 false))
(for/list ([i l1] [j l2] [k l3])
          (list i j k))

;; → '((a 1) (b 2) (c 3))
(for/list ([i l1] [j l2])
          (list i j))

;; → '()
(for/list ([i l1] [j l2] [k null])
          (list i j k))

答案 5 :(得分:0)

今天,我遇到了同样的练习,并做了我自己的实现,这与这里发布的所有实现都不同。所有其他答案都很棒。我真的很喜欢@Alinsoar 中投票最多的一个。

当然,其他答案实际上比我的实现要好。但无论如何我都会发布它。也许,这可以帮助尝试学习 Racket 的人。


(define (shorter-list xs ys)
  (if (> (length xs) (length ys))
      ys
      xs))

(define (zip xs ys)
  (cond [(null? (shorter-list xs ys)) null]
        [true (cons (list (car xs) (car ys)) (zip (cdr xs) (cdr ys)))]))