递归比较两个列表中的每个项目,return 个具有最小项目的新列表

Recursively compare each item from two lists, return new list with smallest items

在 Scheme/Racket

中执行此操作

问题是:取两个等长的数字列表,然后return一个由最小数字逐个位置组成的列表。

例如:listMins( '(1 7 5) '(2 8 3) )

returns (1, 7, 3) 因为 1<27<83<5

我是函数式编程的新手,不擅长递归。我觉得好像我只是遗漏了一些我不知道如何在我的伪代码中解决的关键部分,这样我就可以开始真正地编码了。 (我尝试先跳转到代码,但没有用,所以我退后一步看伪代码。)

伪代码:

(listMins x, y)(
    (if !null A)
        (if > listAitem listBitem)
            (add A to newList) ;where do I make newList?
            (add B to newList)
        (return newList)
)

如果你使用像 map 这样的高阶函数,这实际上非常容易,特别是因为 Scheme 的 map 可以接受许多参数,在这种情况下它就像一个 "zip" 函数.这意味着可以在一行简洁的代码中实现 list-mins 函数:

(define (list-mins . lsts)
  (apply map min lsts))

不过,这使用了一些相对复杂的 Scheme/Racket 机制,因此可能不太清楚发生了什么。带点的参数,与 apply 配对允许 list-mins 接受任意数量的列表,但你实际上只需要它接受两个,所以这里有一个更简单的版本:

(define (list-mins a b)
  (map min a b))

这是做什么的?那么,map 并行迭代其参数,对每组元素应用一个过程,然后生成一个包含结果元素的新列表。 min 函数只是 returns 其参数的最小值。要查看实际效果,上面的代码基本上是这样做的:

   (map min '(1 7 5) '(2 8 3))
=> (list (min 1 2)
         (min 7 8)
         (min 5 3))
=> (list 1 7 3)

当然,也可以使用递归自己编写。手动执行将如下所示:

(define (list-mins a b)
  (if (empty? a)
      '()
      (cons (min (first a) (first b))
            (list-mins (rest a) (rest b)))))

这几乎只是展开了 map 所做的事情,直接使用 map 更加清晰(它表达了您要迭代一组列表的意图),所以它会更比自己做递归更惯用。不过,如果你正在学习,那么显式版本可能会更清楚。