【问题标题】:Ordering a List of Pairs订购一对列表
【发布时间】:2013-11-09 15:25:13
【问题描述】:

谁能给我一个写得很好的实现,说明如何使用辅助函数(基于每对的汽车的值)在方案中订购一对列表?例如,'((3 2) (1 2) (8 4) (0 6)) 应按 '((0 6) (1 2) (3 2) (8 4)) 排序。这似乎是一件很简单的事情,但出于某种原因,我画了一个空白。

【问题讨论】:

  • 顺便说一下,如果你不想给我确切的代码,我会对基本情况感到满意。这是一个更大的程序的一部分,我想确保它是正确的。

标签: recursion scheme


【解决方案1】:

好吧,首先你可以使用你最喜欢的内置sort 例程,并指定它按car 排序,例如在通用 LISP 中

(sort ls #'< :key #'car)

如果您的 Scheme 缺乏指定 key 的能力,您可以通过比较过程来模拟这一点

(sort ls (lambda (a b) (< (car a) (car b))))

其次,如果你想重新实现它,你可以使用合并排序的方法:将你的列表分解成单调递增的部分,然后将它们两两合并,直到只剩下一个。在 Haskell 中,

mergesortBy f xs 
   | null xs       = []
   | [s] <- until (null.tail) (pairwise (mergeBy f)) (breakup xs) = s
pairwise g (a:b:t) = g a b : pairwise g t
pairwise _ t       = t
breakup xs         = [[x] | x <- xs] -- a list of (a list of x) for x in xs

由于这些部分是单调递增的(或至少是非递减的),mergeBy 可以很容易地实现。

当然,“编写良好”的实现将用初始阶段替换此处显示的基本breakup,该阶段将尝试生成更长的块,在旅途中保留非减少和反转非增加块( Haskell 的例子是here)。 pairwisemergeBy(甚至可能是 breakup)函数必须融合为一个,以使整体实现更加在线,因为 Scheme(通常)是一个严格的 (即非惰性)语言。您可以在要合并的内部列表中使用显式暂停,以便从排序列表中取出一些第一个元素is an O(n) operation

【讨论】:

  • 是否有一个更简单的函数我可以使用我自己创建的辅助函数来创建自己?你提供给我的很多功能我都不熟悉,对Scheme的研究也不太深入。
  • 你可以把 Haskell 当作伪代码来读,然后用 Scheme 写下来。您确实说过(在评论中)您不需要“确切代码”。 :) 你的 Scheme 有 sort 函数吗?那么我回答中的第二个代码 sn-p 就是你想要的; lambda 是辅助函数,你可以把它拉到一边并给它一个名字:(define (my-compare a b) (&lt; (car a) ...))。您可以在 Wikipedia 上阅读各种排序算法(包括合并排序)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-14
  • 1970-01-01
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多