2017-09-23 11 views
0

スキームランレングス符号化

原子Lのリストを取る関数(エンコードL)を書き込み、ランレングスは、(出力形式のペアのリストであることがリストは、コード値の長さ)ここで、最初の要素は値で、2番目は値がエンコードされたリストで発生する回数です。例えば

(encode '(1 1 2 4 4 8 8 8)) ---> ((1 2)(2 1)(4 2)(8 3)) 

これは今のところ私が持っているコードです:

(define (encode lst) 
    (cond 
    ((null? lst) '()) 
    (else ((append (list (car lst) (count lst 1)) 
        (encode (cdr lst))))))) 

(define (count lst n) 
    (cond 
    ((null? lst) n) 
    ((equal? (car lst) (car(cdr lst))) (count (cdr lst) (+ n 1))) 
    (else (n))))) 

は、だから私は、この文句を言わない仕事を知っている私は本当に数をカウントする方法を考えるカントので、リスト内の特定のアトムを効果的に削除することができます。また、前の(値の長さ)のペアを保存してから、リスト内の次の一意の原子をカウントするまで移動します。基本的には、私の主な問題は、私の(値の長さ)のペアを作成するためにリストに表示されている原子の量のカウントを維持する方法を考え出しています。

答えて

1

追加の引数としてカウントを持つヘルパー関数が必要です。最初の2つの要素を互いに照合してチェックし、一致した場合は残りの要素の数を増やしたり、再帰呼び出しの回数を1にリセットして再帰的に再帰します。 let表現

状態変数を再帰的ヘルパープロシージャの使用この手法は非常にあるという名前のを使う

(define (encode lst) 
    (define (helper lst count) 
    (cond ((null? lst) <??>) 
      ((null? (cdr lst)) <??>)) 
      ((equal? (car lst) (cadr lst)) <??>) 
      (else (helper <??> <??>)))) 
    (helper lst 1)) 

;; tests 
(encode '())    ; ==>() 
(encode '(1))    ; ==> ((1 1)) 
(encode '(1 1))   ; ==> ((1 2)) 
(encode '(1 2 2 3 3 3 3)) ; ==> ((1 1) (2 2) (3 4)) 

:ここ

あなたが<??>部品を実装する必要がスケッチですSchemeではよくあるパターンであるletという形式があります。これにより、パターンを少し良く表現できます

あなたの質問内のコード上
(define (encode lst) 
    (let helper ((lst lst) (count 1)) 
    (cond ((null? lst) <??>) 
      ((null? (cdr lst)) <??>)) 
      ((equal? (car lst) (cadr lst)) <??>) 
      (else (helper <??> <??>))))) 

コメント:それは余分な括弧を持っている...

((append ....))手段は、それが関数であるかのように、その結​​果を呼び出し(append ....)を呼び出します。 appendは、悲惨に失敗するリストをERROR: application: expected a function, got a listのようにします。

(n)は、nのような変数であることを覚えておいてください。+は単なる変数です。機能やスキーム内の他の値との間に違いありません、あなたはそれを呼び出すために括弧でそれをラップしている場合、それは関数に評価する必要がある(if (< v 3) + -)のような表現を入れたときに((if (< v 3) + -) 5 3); ==> 8 or 2

+0

私はこれを正しく実装したコードを、追加することができました必要です。これは今私にとってはるかに理にかなっています。 – Frank

+1

@Frankをお手伝いします。変数の変更を模倣するための引数を追加するトリックは、通常、Schemeの問題の解決策です。 Schemeには、関数名を失うことなくletのように書くための名前付きletという名前があります。 – Sylwester

+0

@Sylwesterあなたのコメントにあなたが記述した名前の 'let'フォームを使ってコードを修正しました^ _^ – naomik