MIT方案列表按升序排序

时间:2013-04-14 16:13:03

标签: list sorting scheme procedure

我正在参加一个关于麻省理工学院计划的编程课程的练习考试。其中一个问题是:

“完成程序(按顺序ls)返回列表ls,除了在严格大于的第一个值之前停止,而不是ls中的前一个值。换句话说,在-order应该从开始的开始返回按严格递增的顺序排序的部分。假设ls只包含非负整数。“

然后问题显示了几个例子:

(in-order '(1 2 3 4)) ; should return (1 2 3 4)
(in-order '(1 2 3 3 4 5)) ; should return (1 2 3)
(in-order '(3 2)) ; should return (3)
(in-order '(3)) ; should return (3)

这是我尝试解决方案:

(define (in-order ls)
  (cond ((null? ls) ls)
        ((< (car ls) (cadr ls)) 
         (cons (car ls) (cons (in-order (cdr ls)) ())))
        ((>= (car ls) (cadr ls)) (car ls))
        (else "Nothing")))

接近使用第二和第三个例子,但是第一个和第四个例子彻底失败了。我知道它一直试图传递null作为参数的一部分,但我不确定如何解决这个问题。除此之外,还有什么我错了吗?

1 个答案:

答案 0 :(得分:2)

这可以帮助你:

(define (in-order ls)
  (if (null? ls)
      '()
      (let looking ((result (list (car ls))) (ls (cdr ls)))
        (if (or (null? ls) (not (< (car result) (car ls))))
            (reverse result)
            (looking (cons (car ls) result)
                     (cdr ls))))))

尾递归looking总是将最后一个值作为结果car。因此,停止的比较变为(not (< (car result) (car ls)))

在您的代码中,(cons (in-order ...) ())几乎肯定是错误的。谓词(< (car ls) (cadr ls))会因'(3)之类的内容而失败 - 您需要(null? (cdr ls))这样的内容来避免这种情况。

在非尾递归算法中,与您的类似,它将是:

(define (in-order ls)
  (cond ((or (null? ls) (null? (cdr ls))) ls)     ; nothing left
        ((< (car ls) (cadr ls))                   ; extend and continue
         (cons (car ls) (in-order (cdr ls))))
        (else (list (car ls)))))                  ; last one