【问题标题】:Sorting a list of pairs based on the second element in Scheme根据 Scheme 中的第二个元素对对列表进行排序
【发布时间】:2013-11-13 18:09:11
【问题描述】:

有人可以给我一些建议,告诉我如何编写代码来根据每对的第二个元素按升序对一对列表进行排序吗?我没有给你一个例子,但这似乎是一件容易想象的事情。

【问题讨论】:

  • 有人可以在不使用内置方案函数的情况下编写此函数吗?还是不可能?
  • @JohnFriedrich:步骤 1)编写一个带有“cmp”参数的排序函数。步骤 2) 使用比较列表的第二个元素的“cmp”参数调用它。所以你的问题简单地归结为,如何在方案中编写排序函数?
  • @JohnFriedrich 有比 O(n²) 更快的排序算法,所以不必非常失望。 (最快的有 O(n log n) 最坏情况时间;我相信不可能再快了。)
  • @ChrisJester-Young 你肯定忘了en.wikipedia.org/wiki/Integer_sorting ... :)

标签: list sorting scheme


【解决方案1】:

让我们尝试编写一个归并排序。

(define (mgsort ls cmp)
  (cond
    ((or (null? ls) (null? (cdr ls)))
       ls)
    ; right? ... then,
    (else 
      (split ls '() '() cmp))))

处理列表最基本的工具是结构递归:

(define (split ls a b cmp)
  (cond 
    ((null? ls) 
       (merge (mgsort a cmp) (mgsort b cmp) cmp))
    (else
       (split (cdr ls) b (cons (car ls) a) cmp))))

现在剩下的就是写merge——一个可以合并的函数,就像“zipping”一样,它的两个参数是排序列表,所以结果也是一个排序列表。

(define (merge a b cmp)
  (cond 
    ((null? a) b)
    ((null? b) ....)
    ((cmp (car a) (car b))   ; right?
       (cons   
          ... ;; what? ... with what??
          (merge (cdr a) ......)))
    (else
       (cons
          ... 
          (merge a ......)))))

测试:

(mgsort (list 3 1 5 4 6 2 3) <)
;Value 12: (1 2 3 3 4 5 6)

(mgsort (list (cons 3 1) (cons 4 5) (cons 6 2)) (lambda(a b) (< (cdr a) (cdr b))))
;Value 13: ((3 . 1) (6 . 2) (4 . 5))

参见。 how would one merge two strings that are ordered alphabetically in lisp using recursion 用于高效的自上而下的合并功能(虽然在 Common Lisp 中,名义上用于字符串,但它确实适用于内部列表),尾递归模 cons 优化技术的手动实现。

【讨论】:

  • 谢谢,这看起来更像我能理解的东西,因为我对 Scheme 比较陌生。
猜你喜欢
  • 2011-05-21
  • 2021-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
相关资源
最近更新 更多