2017-03-29 10 views
1

ラケットが新しく、リストが厳密に昇順であるかどうかをチェックする関数を書こうとしています。ラケットのリストの昇順を確認してください

'(1 2 3)trueを返します '(1 1 2)(3 2 4)返します」 を偽(繰り返し)を返す偽

私のコードは、これまでのところです: 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

コードの画像を投稿しないでください。実際の質問にあなたのコードを入れてください。 –

+0

さて、ちょうど上に投稿! – Vic

答えて

2

いくつかの関数を書くときに考慮すべき事柄:変数名としての機能に組み込まれて使用して

  • は避けてください。たとえば、listは、新しく割り当てられたリストを返す組み込みプロシージャなので、関数の引数として、または変数として使用しないでください。一般的な規則/代替方法は、lstをリストの変数名として使用することです。したがって、(define (ascending? lst) ...)を持つことができます。
  • 変数名を引用しないでください。たとえば、(define lst '(1 2 3 ...))で、(define 'lst '(1 2 3 ...))ではありません。
  • テストする条件が複数ある場合(つまり2を超える場合)、複数のif文をネストするのではなく、condを使用するときれいになる場合があります。

あなたは(> first (first (rest list)))を持っている3行に注意して、('listを交換した後)ascending?の実装を修正します。ここでは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はネストされたifよりもはるかに理にかなっています。他のヒントもありがとう! – Vic

3

私はあなたを推測します最初から手続きを実装したいと思っています。そして、Alexanderの答えは現実的です。しかし、実際の関数型プログラミングでは、既存のプロシージャを再利用してソリューションを書くべきです。これは私が何を意味するかです:

(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

あなたは箇条書き形式で昇順リストのプロパティを書き留めた場合は、

昇順リストが空リスト

  • のいずれかである、又は
  • 1要素のリスト、又は
    • 最初の要素は小さいリスト第2の要素よりも、および
    • リストの末尾には、あなたはかなりまっすぐ翻訳を巻くことができ

を昇順です:

(define (ascending? ls) 
    (or (null? ls) 
     (null? (rest ls)) 
     (and (< (first ls) (first (rest ls))) 
      (ascending? (rest ls))))) 
関連する問題