检查Racket中列表的升序

时间:2017-03-29 02:15:23

标签: recursion scheme lisp racket

我是新手,并试图编写一个函数来检查列表是否严格按升序排列。

'(1 2 3)将返回true '(1 1 2)将返回false(重复) '(3 2 4)将返回false

到目前为止我的代码是: Image of code

(define (ascending? 'list)
   (if (or (empty? list) (= (length 'list) 1)) true
      (if (> first (first (rest list))) false
          (ascending? (rest list)))))

我正在试着提升?递归地我的基本情况是列表是空的或只有1个元素(然后是平凡的升序)。

当我使用check-expect表示“应用程序:不是程序”时,我不断收到错误消息。

4 个答案:

答案 0 :(得分:3)

我想你想从头开始实施一个程序,亚历山大的回答是现实的。但是在真正的函数式编程风格中,您应该尝试重用现有的过程来编写解决方案。这就是我的意思:

(define (ascending? lst)
  (apply < lst))

它更短,更简单,更容易理解。它按预期工作!

(ascending? '(1 2 3))
=> #t

(ascending? '(1 1 2))
=> #f

答案 1 :(得分:2)

编写函数时需要考虑的一些事项:

  • 避免将内置函数用作变量名。例如,list是一个内置过程,它返回一个新分配的列表,因此不要将它用作函数的参数或变量。一个常见的约定/替代方法是使用lst作为列表的变量名称,因此您可以拥有(define (ascending? lst) ...)
  • 不要引用您的变量名称。例如,您将(define lst '(1 2 3 ...))而不是(define 'lst '(1 2 3 ...))
  • 如果您有多个要测试的条件(即超过2个),使用cond而不是嵌套多个if语句可能更清晰。

要修复ascending?的实施(替换'list后),请在第3行注明(> first (first (rest list)))。您在这里将first(first (rest list))进行比较,但您真正想要的是将(first lst)(first (rest lst))进行比较,因此它应该是(>= (first lst) (first (rest lst)))

以下是一个示例实现:

(define (ascending? lst)
  (cond
    [(null? lst) #t]
    [(null? (cdr lst)) #t]
    [(>= (car lst) (cadr lst)) #f]
    [else
     (ascending? (cdr lst))]))

或者如果您想使用first/resttrue/false,您可以执行以下操作:

(define (ascending? lst)
  (cond
    [(empty? lst) true]
    [(empty? (rest lst)) true]
    [(>= (first lst) (first (rest lst))) false]
    [else
     (ascending? (rest lst))]))

例如,

> (ascending? '(1 2 3))
#t
> (ascending? '(1 1 2))
#f
> (ascending? '(3 2 4))
#f

答案 2 :(得分:0)

此Scheme解决方案使用名为letmemoization的显式递归

(define (ascending? xs)
   (if (null? xs) #t                    ; Edge case: empty list
      (let asc? ((x (car xs))           ; Named `let`
                 (xs' (cdr xs)) )
         (if (null? xs') #t
            (let ((x' (car xs')))       ; Memoization of `(car xs)`
               (if (< x x')
                  (asc? x' (cdr xs'))   ; Tail recursion
                  #f))))))              ; Short-circuit termination

(display
   (ascending?
      (list 1 1 2) ))                   ; `#f`

答案 3 :(得分:0)

如果您以子弹形式记下升序列表的属性;

升序列表是

  • 空列表
  • 单元素列表
  • 列表在哪里
    • 第一个元素小于第二个元素
    • 列表的尾部是升序

你可以用一个非常直接的翻译结束:

(define (ascending? ls)
  (or (null? ls)
      (null? (rest ls))
      (and (< (first ls) (first (rest ls)))
           (ascending? (rest ls)))))