0

我需要帮助完成一个解压缩函数,该函数接受一个压缩列表并返回一个包含两个列表的列表。我想要的结果如下...

(unzip '((a b) (1 2)))
'((a 1) (b 2))

(unzip '((a 1) (b 2) (c 3)))
'((a b c) (1 2 3))

(unzip '(unzip '()))
'(() ())

我可以让我的代码适用于 null 情况并使用包含两个列表的列表,但我很难弄清楚如何使其递归并适用于超过 2 个列表,例如第二个示例。

(define (unzip l)
  (if (null? l) 
      '(() ())
      (map list (car l) (car (cdr l)))))

这适用于一个空列表或两个列表,但我很难设置递归部分来处理三个或更多列表。

4

3 回答 3

4

这是一个非常标准的操作,相当于查找列表列表的转置。它通常是这样实现的:

(define (unzip lst)
  (apply map list lst))

它适用于前两个示例。第三个,我认为定义不明确,但如果你想让它适用于那个奇怪的情况,我会把它留作练习;)

请注意,如果您unzip是一个解压缩的列表,您会得到原始输入......这unzip也是zip

(unzip '((a b) (1 2) (x y)))
=> '((a 1 x) (b 2 y))

(unzip '((a 1 x) (b 2 y)))
=> '((a b) (1 2) (x y))
于 2013-06-24T11:58:42.120 回答
1
(apply map list '((a 1) (b 2) (c 3) (d 4) (e 5)))

;Value 16: ((a b c d e) (1 2 3 4 5))

这样做。顺便说一句,同样的技巧也适用于压缩,前提是所有列表的长度相同:

(apply map list (list '(a b c d e) '(1 2 3 4 5)))

;Value 17: ((a 1) (b 2) (c 3) (d 4) (e 5))
于 2013-06-24T11:58:51.027 回答
0

你知道在 Scheme 中一个函数可以返回多个值吗?

(define (unzip list)
  (values (map car  list)
          (map cadr list)))

然后像这样使用它:

(let-values ([(z1 z2) (unzip '((a 1) (b 2)))])       
   ;; Use z1 and z2
   ...)
于 2013-06-24T14:31:36.767 回答