在方案中对列表进行排序

时间:2013-05-28 17:16:21

标签: scheme

我想创建排序列表的功能。例如,我有这个列表:

x1, x2, x3 .... xn

1, 2, 3, 4, 5, 6

我想按此顺序显示数字:

x1, xn, x2, xn-1

1, 6, 2, 5, 3, 4

你能帮我写这个例子吗?

2 个答案:

答案 0 :(得分:4)

通常当我们谈论排序时,我们指的是通过项目内容的某些特征来排序项目,而不是列表中的项目位置。我会打电话给你的情况,但也许有些人可能会对这种用法提出异议。 : - )

以下是解决问题的方法:

  1. 在中间拆分列表(如果你只想遍历列表一次,你可以使用乌龟和野兔);如果您愿意,可以调用这些列表headtail
  2. 撤消tail列表,并将其与head列表交错。
  3. 另一种方法:

    1. 反转原始列表对(我们称之为rev)。
    2. 使用rev交换原始列表,跟踪每次遍历的元素。当他们在中间见面时,停下来。
    3. 以下是第二种方法的演示(需要加载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))))))))
      

答案 1 :(得分:3)

这不是一个真正的分类操作,更像是一个改组;这是另一种解决方法。首先,让我们定义interleave过程来替换两个列表中的元素,返回一个列表:

(define (interleave l1 l2)
  (cond ((empty? l1) l2)
        ((empty? l2) l1)
        (else (cons (first l1)
                    (interleave l2 (rest l1))))))

现在我们采用原始列表和split-at中间(这是一个特定于球拍的程序);最后,我们将两个结果列表交错,反转尾部:

(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)