方案反向列表函数

时间:2015-10-17 16:42:57

标签: list recursion functional-programming scheme

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

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

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

2 个答案:

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

当你使用它时,它有点困难但不多:

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

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

zip usually implemented applymap,并列出并生成列表列表,如下所示:

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