Racket:递归地比较列表中的元素

时间:2017-10-03 21:16:17

标签: recursion scheme racket

这个函数应该是一个列表(充满字符串或整数,这就是为什么它以'if'语句开头),并检查它是否按升序排列。

我无法弄清楚如何防止它崩溃,因为在最后一次递归调用中,'cadr'没有什么可以拉动的,因为'car'是最后一个元素。

(define (my-sorted? lst)  
   (if (number? (car lst))
     (if (< (car lst) (cadr lst))
        (my-sorted? (rest lst))      
         #f)     
     #f) 
 )

我知道sort函数存在,但我需要递归地实现这个函数。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您应该尝试的两个最基本的列表是:

(my-sorted? '())  ; ==> #t (empty list is always sorted)
(my-sorted? '(1)) ; ==> #t (one element list is always sorted)

您当前的代码只对其参数执行了carcadr,因此在这两个测试中,它将在不同级别失败。

如何比较一个数字和一个不是数字的东西。 <期望两个参数都是数字,但您的列表可以是字符串和数字。 "x"7的较小者是什么?你做不到(< 7 "x")

您可以考虑if而不是嵌套cond,这是做if-elseif-else的lisps方式。基本上,您可以使用cond执行代码,如下所示:

(cond 
  ((not (number? (car lst))) #f)
  ((< (car lst) (cadr lst)) (my-sorted? (rest lst))
  (else #f))

修改

由于列表应该是所有元素作为字符串或全部作为数字,您只需通过查看第一个元素来确定比较函数,并使用命名的let进行递归并重用基于第一要素。

(define (my-sorted lst)
  ;; determine what comparison function to use, bind it to greater?
  (define greater? 
    (if (and (pair? lst) (number? (car lst)))
        >
        string>?))

  ;; main recursive loop uses that one function
  ;; this can be done with define + call as well
  (let loop ((lst lst))
    (cond ((or (null? lst) (null? (cdr lst))) ...)
          ((greater? (car lst) (cadr lst)) ...)
          (else (loop ...)))))