2015-10-17 40 views
1

我定义了一个称为zip的函数,它将两个列表作为参数并返回一个列表对。Scheme Inverse List Function

(define (zip list1 list2) 
(if (null? list1) 
    '() 
    (cons (list (cons (car list1) (car list2))) 
      (zip (cdr list1) (cdr list2))))) 

(zip (list 1 3 5) (list 2 4 6)) 
> (((1 . 2)) ((3 . 4)) ((5 . 6))) 

现在我基本上在写这个反函数时遇到了麻烦。这是我迄今为止所拥有的。该功能需要输出两个列表的列表。我只是试图使两个列表中的第一个让我更容易,但输出不是我想要的。

(define (unzip u-list) 
    (if (null? u-list) 
     '() 
     (list (car (car (car u-list))) (unzip(cdr u-list))))) 


(unzip (zip (list 1 3 5) (list 2 4 6))) 
> (1 (3 (5()))) 

任何帮助,将不胜感激......

回答

4

我相信有您的实现的zip一个问题,你有没有注意到,你回来对单元素列表的一个列表?返回对列表更有意义:

(define (zip lst1 lst2) 
    (if (null? lst1) 
     '() 
     (cons (cons (car lst1) (car lst2)) 
      (zip (cdr lst1) (cdr lst2))))) 

甚至更​​好,让我们使用map高阶函数较短,更地道的解决方案:

(define (zip lst1 lst2) 
    (map cons lst1 lst2)) 

关于unzip:如果我们更容易把问题分成几部分 - 让我们得到每一对的第一个元素,然后得到每一对的第二个元素,最后用答案建立一个列表。试试这个:

(define (unzip lst) 
    (define (firsts lst) 
    (if (null? lst) 
     '() 
     (cons (caar lst) 
       (firsts (cdr lst))))) 
    (define (seconds lst) 
    (if (null? lst) 
     '() 
     (cons (cdar lst) 
       (seconds (cdr lst))))) 
    (list (firsts lst) (seconds lst))) 

但我们再一次重新发明了方向盘。让我们只使用内置函数编写一个简单的答案:

(define (unzip lst) 
    (list (map car lst) (map cdr lst))) 

反正现在unzipzip倒数:

(zip '(1 3 5) '(2 4 6)) 
=> '((1 . 2) (3 . 4) (5 . 6)) 

(unzip '((1 . 2) (3 . 4) (5 . 6))) 
=> '((1 3 5) (2 4 6)) 
+1

很好的答案。感谢分享。 – naomik

+0

感谢您的帮助!这现在更有意义。 – spidey2623

1

正如你对做它,它是较为困难的,但没有太多:

(define (zip-pair a b) 
    (map cons a b)) 

(define (unzip-pair zipped-pair) 
    (list (map car zipped-pair) 
     (map cdr zipped-pair))) 

zipusually implementedapplymap并采取列表产生清单列表,如下:

(define (zip . lists) 
    (apply map list lists)) 

(zip '(1 2 3) '(a b c)) ; ==> ((1 a) (2 b) (3 c)) 

虽然这将使列表而不是对。然而,解压缩几乎是相同的,除了你会采取列表而不是可变数量的参数:

(define (unzip1 zipped-list) 
    (apply map list zipped-list)) 

; or reuse zip 
(define (unzip1 zipped-list) 
    (apply zip zipped-list)) 

(unzip1 '((1 a) (2 b) (3 c))) ; ==> ((1 2 3) (a b c)) 
+0

所以'zip'是它自己的逆(几乎)。不错。 :) –