简体   繁体   English

方案反向列表功能

[英]Scheme Inverse List Function

I defined a function called zip which took two lists as parameters and returned a list of pairs. 我定义了一个名为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)))

Now I'm basically having trouble writing the inverse function of this. 现在,我基本上无法编写此函数的逆函数。 This is what I have so far. 到目前为止,这就是我所拥有的。 This function needs to output a list of two lists. 此功能需要输出两个列表的列表。 I only attempted at making the first of the two lists to make it easier for myself but the output is not what I want. 我只是试图使两个列表中的第一个变得更容易,但是输出不是我想要的。

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

Any help would be appreciated... 任何帮助,将不胜感激...

I believe there's a problem with your implementation of zip , did you notice that you're returning a list of single-element lists of pairs? 我相信zip的实现存在问题,您是否注意到要返回一个成对的单元素列表? returning a list of pairs makes more sense: 返回对列表更有意义:

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

Or even better, let's use the map higher-order function for a shorter, more idiomatic solution: 甚至更好,让我们使用map高阶函数来获得更短,更惯用的解决方案:

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

Regarding unzip : it's easier if we split the problem in parts - let's get the first element of each pair, then the second element of each pair, and finally build a list with the answer. 关于unzip :将问题分成几部分会更容易-让我们获取每对的第一个元素,然后获取每对的第二个元素,最后建立包含答案的列表。 Try this: 尝试这个:

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

But once again, we're reinventing the wheel. 但是再次,我们正在重新发明轮子。 Let's just use built-in functions to write a simpler answer: 让我们只使用内置函数来编写一个更简单的答案:

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

Anyway, now unzip is the inverse of zip : 无论如何,现在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))

As you make it with pairs it's somewhat more difficult but not much: 当您配对时,难度会增加一些,但不会很多:

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

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

zip is usually implemented with apply and map and takes list and produce list of lists, like this: zip 通常是通过applymap 来实现的 ,并采用list并产生list列表,如下所示:

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

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

Though this will make lists and not pairs. 虽然这将使列表而不是配对。 However a unzip is almost the same except that you will take a list of lists instead of variable number of arguments: 但是,解压缩几乎相同,除了您将使用列表列表而不是可变数量的参数:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM