【问题标题】:Scheme "Merge" function implementationScheme“合并”功能实现
【发布时间】:2014-02-19 01:35:21
【问题描述】:

我正在尝试使用 Scheme 创建一个 Merge2 函数,该函数采用 2 个有序列表并将它们组合成一个有序列表。例如(merge2 '(1 3 4) '(2 4 5)) 将产生(1 2 3 4 4 5)

这是我的尝试。我觉得这应该可行,我只需检查每个列表的每个carmin,然后将此min 附加到merge2 的递归调用中。然后我的基本情况是当列表中的 1 个变为空时,它应该只返回要附加的另一个列表。

(define (merge2 a b)
    (if (and (null? a) (null? b))
        `())
    (if (null? a) b)
    (if (null? b) a)

    (display a)
    (display b)

    (if (= (min (car a) (car b)) (car a)) 
        (append (list (min (car a) (car b))) (merge2 (cdr a) b)))

    (if (= (min (car a) (car b)) (car b)) 
        (append (list (min (car a) (car b))) (merge2 a (cdr b))))) 

这个输出:

(1 2 4)(2 3 4)(2 4)(2 3 4)(4)(2 3 4)(4)(3 4)(4)(4)()(4)
类型错误:无法调用未定义的方法“应用”[merge2、merge2、merge2、merge2、merge2、merge2、car、merge2、merge2、merge2、merge2、merge2、merge2、car、merge2、merge2、merge2、merge2、merge2、merge2 , 汽车]

【问题讨论】:

    标签: scheme


    【解决方案1】:

    解决方案更简单,利用两个列表都排序这一事实,并从一个元素中选择一个元素,然后根据哪个元素更大,直到其中一个列表结束。这就是我的意思:

    (define (merge lst1 lst2)
      (cond ((null? lst1) lst2)
            ((null? lst2) lst1)
            ((>= (car lst1) (car lst2))
             (cons (car lst2) (merge lst1 (cdr lst2))))
            (else
             (cons (car lst1) (merge (cdr lst1) lst2)))))
    

    它按预期工作:

    (merge '(1 3 4) '(2 4 5))
    => '(1 2 3 4 4 5)
    

    【讨论】:

    • 这似乎非常接近我的目标。我想我还没有完全掌握语法。谢谢你
    【解决方案2】:

    您可能遇到的部分问题是,Scheme 作为一种函数式编程语言,是面向表达式的,而不是命令式的。因此,用 Scheme 编写的每件事都有一个值,甚至是条件表达式。一切都是一个表达式,并被评估以产生结果。当您坚持纯函数式编程风格(Scheme 鼓励,但不严格强制执行)时,会对表达式求值以产生一个结果,该结果可以成为另一个要求值的表达式的一部分。表达式只是简单的求值,它们不是导致计算机内存状态发生某种变化的过程;函数式编程风格没有副作用。所以,你应该从条件表达式的角度来考虑条件处理。

    在命令式编程世界中,我能想到的最接近的对应物是 C 或 Java 的 ?: 运算符。您的函数以一系列条件表达式开始,但它们就像 C 或 Java 中的一系列条件表达式,没有分配给任何东西,因此结果被“丢弃”。

    相反,开始思考这些术语:我们希望将两个列表合并在一起,那么如果其中一个为空,那么将两个列表合并在一起意味着什么?这为合并两个列表的迭代过程形成了一种“基本情况”或终止条件。

    另外:如果两个列表都不为空,那么将它们合并在一起意味着什么?如果我们可以根据现有列表(即归纳步骤)用更小的列表来表达解决方案,那么我们就可以开始了解递归过程的样子了。

    因此,此归纳步骤的部分解决方案将涉及某种表达式,该表达式基于检查每个列表的 car 以查看应将哪个放在合并剩余列表的开头。如果(car a) 小于或等于(car b) 那么(car a) 可以成为(merge2 (cdr a) b) 的第一个元素,对吧?这假设有一种方法可以计算(merge (cdr a) b),当然!

    所以,听起来我们在谈论一个条件表达式,它将成为更大的定义或表达式的一部分,它说明了将两个列表合并在一起的含义:

    (cond ((<= (car a) (car b)) (cons (car a) (merge2 (cdr a) b) ) )
           ...there's more to write here to finish the conditional expression )
    

    我希望这有助于更清楚地说明 Oscar Lopez 是如何得出他的解决方案的;可以看到我上面开始写的条件表达式也在他呈现的函数中!

    其中一个关键部分是从递归过程和递归定义的角度进行思考。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-17
      • 2021-06-04
      • 2021-04-25
      • 1970-01-01
      • 2022-09-22
      • 2017-03-30
      • 2014-03-08
      • 1970-01-01
      相关资源
      最近更新 更多