在scheme中对列表排序
我想创建对列表排序的函数。例如,我有以下列表:在scheme中对列表排序,scheme,Scheme,我想创建对列表排序的函数。例如,我有以下列表: x1, x2, x3 .... xn 或 1,2,3,4,5,6 我想按以下顺序显示数字: x1, xn, x2, xn-1 或 你能帮我写一下这个例子吗?通常,当我们谈到排序时,我们指的是根据项目内容的某些特征对项目进行排序,而不是项目在列表中的位置。我会把你的情况称为排列,但也许有些人也会对这种用法提出异议。:-) 以下是解决问题的方法: 在中间分割列表(如果你只想遍历该列表,你可以使用龟兔);如果需要,可以调用那些列表head和tail
x1, x2, x3 .... xn
或
1,2,3,4,5,6
我想按以下顺序显示数字:
x1, xn, x2, xn-1
或
你能帮我写一下这个例子吗?通常,当我们谈到排序时,我们指的是根据项目内容的某些特征对项目进行排序,而不是项目在列表中的位置。我会把你的情况称为排列,但也许有些人也会对这种用法提出异议。:-) 以下是解决问题的方法:
head
和tail
尾部
列表,并将其与头部
列表交错rev
)rev
交错,跟踪每次遍历的元素。当他们在中间相遇时,停下来。这不是真正的排序操作,更像是洗牌;这里有另一种解决方法。首先,让我们定义
interleave
过程,该过程交替两个列表中的元素,返回单个列表:
(define (interleave l1 l2)
(cond ((empty? l1) l2)
((empty? l2) l1)
(else (cons (first l1)
(interleave l2 (rest l1))))))
现在我们取原始列表和中间部分(这是一个特定于球拍的程序);最后,我们将两个结果列表交错排列,颠倒尾部:
(define (zippy lst)
(let-values (((head tail) (split-at lst (quotient (length lst) 2))))
(interleave head (reverse tail))))
上面的IMHO实现更加直观,如果您使用Racket,则不需要外部库。它按预期工作:
(zippy '(1 2 3 4 5 6))
=> '(1 6 2 5 3 4)
……斯卡尔·洛佩斯的回答证明了第一种方法+1非常好。:-)非Racket实现的注意事项:
splitat
是的一部分,而let values
是的一部分。如果您的实现没有SRFI 11,您还可以轻松地转换为使用receive
from,或者您也可以直接使用call with value
,尽管后者更难看。:-)顺便说一句,我认为(/(length lst)2)
为奇数长度的列表返回一个非整数,而在处拆分可能不喜欢<代码>(商(长度lst)2)
可能会更好。@ChrisJester Young你当然是对的。修好了,谢谢!我看到一个问题。如果我有以下顺序,如何对数字进行排序:4,2,9,3,5,1
如何对它们进行排序?您在问题中定义的顺序似乎取决于元素的位置,而不是它们的值。如果值相关,则在将列表提供给我的函数之前,先对列表进行排序,然后使用排序
过程
(define (zippy lst)
(let-values (((head tail) (split-at lst (quotient (length lst) 2))))
(interleave head (reverse tail))))
(zippy '(1 2 3 4 5 6))
=> '(1 6 2 5 3 4)