【问题标题】:Finding the intersect of two lists (SML / NJ)查找两个列表的交集(SML / NJ)
【发布时间】:2013-10-12 00:42:18
【问题描述】:

我有一个迭代的 foldr 函数:

fun iterFold f v [] = v
 |   iterFold f v (x::xs) = iterFold f (f(v,x)) xs;

还有一个接受谓词和列表的函数。该函数将列表与谓词进行比较,如果出现一次则返回 true。

fun exist3 p M = foldr( fn(x,y) => y orelse (p x)) false M

使用这两个函数,我需要编写一个返回两个列表交集的单行函数。任何帮助或建议将不胜感激!

【问题讨论】:

    标签: functional-programming sml smlnj fold


    【解决方案1】:

    I have an iterative foldr function.

    不是foldr,而是foldl。区别在于foldr 从列表的最后一个元素到第一个元素,foldl 从列表的第一个元素到最后一个元素。

    他们编写函数的方式:

    fun intersect ls1 ls2 = iterFold (fn (is,l1) =>
                                        if exist3 (fn (l2) => l1 = l2) ls2
                                        then l1::is
                                        else is)
                                     [] ls1
    

    (您可以将其格式化为单行,但我认为您的意思是它应该只调用一个函数)

    这个想法是通过ls1 并添加到同样在ls2 中的结果元素。由于我们是从第一个元素到最后一个元素,因此结果列表中的元素将按照与 ls1 中的顺序相反的顺序出现。

    - intersect [1,2,3] [1,2,3];
    val it = [3,2,1] : int list
    - intersect [2,4,5] [1,2,3,5];
    val it = [5,2] : int list
    

    【讨论】:

    • 上述形式的递归函数(即只有一个递归调用,即尾调用)有时被称为迭代,因为它们完全对应于一个循环。
    • @AndreasRossberg 您能否指出任何这样做的权威来源?或者,这是人们为了方便而通俗地做的事情,而不是说诸如“遍历列表的递归函数”之类的东西?
    • 我可以临时找到的一个指针是 McCarthy 的这些讲义,他谈到了迭代形式的递归方程:www-formal.stanford.edu/jmc/towards/node9.html 从 lambda 演算的角度来看,循环只是一个语法糖这种形式的递归函数。这在 SML 中确实如此:根据语言规范,唯一的循环构造 while e1 do e2 扩展为 let fun f() = if e1 then (e2; f()) else () in f() end。因此,对“迭代”一词的纯句法解释并没有人们想象的那么有用。
    • @zaquest SICP 做到了:mitpress.mit.edu/sicp/full-text/book/…
    • @mazayus SICP 告诉我们一种相反的事情:不要混淆递归过程和递归过程的概念;因此,我认为我们不应该混淆迭代过程和迭代过程的概念。
    猜你喜欢
    • 1970-01-01
    • 2010-10-13
    • 2021-03-18
    • 2012-04-19
    • 2014-05-23
    • 2018-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多