2017-03-29 41 views
1

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

'(1 2 3)将返回真 '(1 1 2)将返回假(重复) “(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个元素(然后细微升序)。

当我使用“应用程序:不是程序”的检查期望时,我总是收到错误消息。

+0

请不要发布的代码图像;把你的代码放在实际的问题中。 –

+0

好的,只是贴在上面! – Vic

回答

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 
+0

太棒了,cond比嵌套的ifs更有意义。并感谢其他技巧! – Vic

3

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

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

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

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

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

看起来很漂亮:) – AsheKetchum

+1

太棒了,非常感谢你! – Vic

0

此方案解决方案使用递归明确命名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` 
0

如果你写在子弹形式的上升列表的属性;

的升序列表要么

  • 空列表,
  • 一个元素列表,
  • 一个列表,其中
    • 第一元素是小比第二个元素,
    • 列表的尾部上升

你可以用一个非常简单的翻译拉闸:

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