【问题标题】:Recursively compare each item from two lists, return new list with smallest items递归比较两个列表中的每个项目,返回具有最小项目的新列表
【发布时间】:2015-11-05 17:33:08
【问题描述】:

在 Scheme/Racket 中执行此操作

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

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

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

【问题讨论】:

    标签: functional-programming scheme racket pseudocode


    【解决方案1】:

    如果您使用像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 函数只返回其参数的最小值。看看这在实际中是什么样子的,上面的代码基本上是这样做的:

       (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 更加清晰(它表达了您对一组列表进行迭代的意图),因此它比进行递归更惯用你自己。不过,如果您正在学习,那么显式版本可能会更清晰。

    【讨论】:

    • 非常,非常有帮助.. 不知何故,我在笔记的carcdr 部分看到了如此狭隘的视野,以至于我完全错过了map... 绝对有助于使这更快它似乎。非常感谢您将 map min 扩展到它正在执行的实际步骤中。这非常有帮助。我最初对如何在函数的“中间”返回一个新数组感到很困惑..关于我正在处理的下一个问题,我仍然在某种程度上,但我至少要再试一个小时半就可以了..再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    相关资源
    最近更新 更多