为什么list-ref无法获得正确的参数?

时间:2011-07-29 03:48:48

标签: scheme racket

我在计划(球拍)中写了一个快速排序

#lang racket

(define (quick-sort xs)
  (let* ([p (list-ref xs 0)]
         [tail (list-tail xs 1)]
         [less (filter (lambda (x) (< x p)) tail)]
         [greater (filter (lambda (x) (>= x p)) tail)])
    (append (quick-sort less) (list p) (quick-sort greater))))

但是当我尝试它时,我收到了这个错误:

> (quick-sort (list 99 2 9922))
list-ref: index 0 too large for list: '()

我是计划的新手所以我不太明白为什么list-ref无法获得正确的输入'(99 2 9922)

编辑:

感谢。我做到了。

#lang racket

(define (quick-sort xs)
  (let* ([p (first xs)]
         [tail (rest xs)]
         [less (filter (lambda (x) (< x p)) tail)]
         [greater (filter (lambda (x) (>= x p)) tail)])
    (if (equal? (length xs) 1) 
      xs
      (append (quick-sort less) (list p) (quick-sort greater)))))

3 个答案:

答案 0 :(得分:3)

当输入列表为空时,您的代码缺少基本情况。发生这种情况时,list-ref会因错误而失败。

顺便说一句,请注意(list-ref l 0)更好的名称是(first l),同样(list-tail l 1)更好地写为(rest l)

(还有carcdr,但如果你是新手,你现在可以忽略它们。)

答案 1 :(得分:3)

在设计递归算法时,有两件事是至关重要的:终止条件和递归步骤,并且没有终止条件。跟踪您的代码正在执行的操作:在您第一次执行quick-sort期间,您将调用:

(append (quick-sort (list 2)) (list 99) (quick-sort (list 9922)))

第一个quick-sort调用将依次调用(quick-sort '())。您的代码不能非常优雅地处理空列表,因为它总是会尝试引用数组的第一个元素作为它的第一个元素。

添加逻辑以正常处理空列表。

此外,使用firstrest获取列表的第一个和剩余元素被认为更加务实。

答案 2 :(得分:0)

您可能已经知道这一点,但Racket也带有内置的sort功能。