【问题标题】:scheme - sorting using accumulate方案 - 使用累积排序
【发布时间】:2012-05-11 15:34:49
【问题描述】:

我想编写一个获取未排序列表(可能包含重复值)的过程,并使用“累积”a.k.a foldr、reduce 等对其进行排序。

我成功过滤了双精度值,但无法对其进行排序。一般来说,我看不到如何使用地图、过滤器、累积……对其进行排序。

我必须在不使用插入排序、冒泡排序的情况下完成它......

这是我现在的代码

(accumulate (lambda (x no-duplicate) (cons x (filter (lambda (z) (not (= x z))) no-duplicate))) '() (list 1 2 0 66 3 4))

【问题讨论】:

  • 请注意:reduce 和accumulate 被称为foldl - 在从左侧遍历序列的同时组装结果...

标签: sorting scheme fold accumulate


【解决方案1】:

您可以简单地实现插入排序。

累积值是迄今为止看到的所有值的排序列表。 当看到一个新值时,它被插入到排序列表中 在正确的地方。为此,请使用相同的 insert 将在插入排序的普通实现中。

您必须编写一个函数insert,它给定一个元素x 和一个排序列表ys,返回一个排序列表,其中包含x 和ys 中的所有元素。将此函数与累加一起使用,一次构建一个元素的最终结果。

【讨论】:

    【解决方案2】:

    另一种方法是tree sort,类似于插入排序(@soegaard 的解决方案),但时间复杂度更高。在这里,您从一棵空树作为初始值开始,并在每次折叠迭代时构建树。

    【讨论】:

      【解决方案3】:

      借用@soegaards 的回答:首先定义一个插入过程,给定一个元素、一个比较过程和一个列表,根据比较过程返回一个包含元素的新列表:

      (define (insert-in-order e cmp lst)
        (cond ((null? lst)
               (list e))
              ((cmp e (car lst))
               (cons e lst))
              (else
               (cons (car lst) (insert-in-order e cmp (cdr lst))))))
      

      现在您可以根据foldrinsert-in-order 实现插入排序过程,它接收要排序的列表和比较过程作为参数:

      (define (insertion-sort lst cmp)
        (foldr (lambda (e acc)
                 (insert-in-order e cmp acc))
               '()
               lst))
      

      像这样使用它:

      (insertion-sort '(4 5 1 1 2 3) <) ; ascending order
      > '(1 1 2 3 4 5)
      
      (insertion-sort '(4 5 1 1 2 3) >) ; descending order
      > '(5 4 3 2 1 1)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-22
        • 2022-11-02
        • 1970-01-01
        • 2013-10-03
        • 2014-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多