针对多个列表的Scheme递归解压缩函数

时间:2013-06-24 11:26:05

标签: function scheme unzip

我需要帮助完成解压缩功能,该功能采用压缩列表并返回两个列表的列表。我想要的结果如下......

(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 case并且列表包含两个列表,但是我很难弄清楚如何使其递归并且工作超过2个列表,例如第二个示例。

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

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

3 个答案:

答案 0 :(得分: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))

答案 1 :(得分: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))

这样做。 BTW同样的技巧也可以用于 zipping ,前提是所有列表都具有相同的长度:

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

答案 2 :(得分: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
   ...)
相关问题