【问题标题】:Check for ascending order of a list in Racket检查 Racket 中列表的升序
【发布时间】:2017-03-29 02:15:22
【问题描述】:

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

'( 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 显示“应用程序:不是过程”时,我不断收到一条错误消息。

【问题讨论】:

  • 请勿发布代码图片;将您的代码放入实际问题中。
  • 好了,贴在上面!!

标签: recursion scheme lisp racket


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 看起来很漂亮:)
【解决方案2】:

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

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

要修复ascending? 的实现(在替换'list 之后),请注意第3 行的(&gt; first (first (rest list)))。这里你是比较first(first (rest list)),但是你真正想要的是比较(first lst)(first (rest lst)),所以应该是(&gt;= (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

【讨论】:

  • 很好,cond 比嵌套的 if 更有意义。并感谢其他提示!
【解决方案3】:

如果你以项目符号的形式写下升序列表的属性;

升序列表

  • 空列表,
  • 单元素列表,
  • 一个列表,其中
    • 第一个元素小于第二个元素,
    • 列表的尾部是升序的

你可以得到一个非常直接的翻译:

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

【讨论】:

    【解决方案4】:

    此 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`
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-05
      • 2023-03-03
      • 2021-01-04
      • 2019-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多