【发布时间】:2013-05-28 17:16:21
【问题描述】:
我想创建对列表进行排序的函数。例如我有这个列表:
x1, x2, x3 .... xn
或
1, 2, 3, 4, 5, 6
我想按这个顺序显示数字:
x1, xn, x2, xn-1
或
1, 6, 2, 5, 3, 4
你能帮我写这个例子吗?
【问题讨论】:
标签: scheme
我想创建对列表进行排序的函数。例如我有这个列表:
x1, x2, x3 .... xn
或
1, 2, 3, 4, 5, 6
我想按这个顺序显示数字:
x1, xn, x2, xn-1
或
1, 6, 2, 5, 3, 4
你能帮我写这个例子吗?
【问题讨论】:
标签: scheme
通常当我们谈论排序时,我们指的是根据项目内容的某些特征对项目进行排序,而不是项目在列表中的位置。我会称您的情况为置换,但也许有些人也会对这种用法提出异议。 :-)
以下是解决问题的方法:
head 和 tail。tail 列表,并将其与head 列表交错。另一种方法:
rev)。rev 交错,跟踪每次遍历的元素。当他们在中间相遇时,停下来。这是第二种方法的演示(需要加载SRFI 1):
(define (zippy lst)
(if (null? lst)
'()
(let recur ((lst lst)
(rev (pair-fold cons '() lst)))
(cond ((eq? lst (car rev)) (list (car lst)))
((eq? (cdr lst) (car rev)) (list (car lst) (caar rev)))
(else (cons* (car lst) (caar rev)
(recur (cdr lst) (cdr rev))))))))
【讨论】:
这并不是真正的排序操作,更像是洗牌;这是解决它的另一种方法。首先,让我们定义interleave 过程,它从两个列表中交替元素,返回一个列表:
(define (interleave l1 l2)
(cond ((empty? l1) l2)
((empty? l2) l1)
(else (cons (first l1)
(interleave l2 (rest l1))))))
现在我们取原始列表和中间的split-at(这是一个特定于Racket的程序);最后,我们将两个结果列表交错,反转尾部:
(define (zippy lst)
(let-values (((head tail) (split-at lst (quotient (length lst) 2))))
(interleave head (reverse tail))))
以上实现恕我直言,更直观一点,如果您使用的是 Racket,它不需要外部库。它按预期工作:
(zippy '(1 2 3 4 5 6))
=> '(1 6 2 5 3 4)
【讨论】:
(/ (length lst) 2) 为奇数长度的列表返回一个非整数,split-at 可能不喜欢。 (quotient (length lst) 2) 可能会更好。
4, 2, 9, 3, 5, 1我如何对它们进行排序?
sort 过程