我是新手,并试图编写一个函数来检查列表是否严格按升序排列。
'(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表示“应用程序:不是程序”时,我不断收到错误消息。
答案 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 ...))
。 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/rest
和true/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解决方案使用名为let
和memoization的显式递归:
(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)))))