2017-05-02 14 views
0

私はスキームを学習しており、割り当てとしてリストを逆転させたり、両方を連結したりしています。すべて再帰的に使用され、組み込みのものを追加または逆に使用しません。スキーム最後の1つを除くリストからすべての繰り返し要素を削除します

私の宿題は、引数としてのみリストを受け取り、すべての繰り返し要素が最後のものを除く他のリストを返す関数を書いています。私は補助機能を使うことができます。

私の考えは、見た目の要素を補助的な再帰関数によってホストされるアキュムレータに蓄積することでした。ベースカーサとして、リストがnullの場合、最初の要素を連結してアキュムレータに保存します。ない場合は、最初の要素を取るとあまりにも補助1に保存しますが、すべての要素と短所以前あなたは、元の最初のリスト要素を挿入したことの新しいリスト、排除:

を連結リストへの

(define (concatena L1 L2) 
    (cond 
     ((null? L1) L2) 
     (else (cons (car L1) (concatena (cdr L1) L2))) 
    ) 
) 

リストL2からすべてのL1要素を排除

(define (elimina L1 L2) 
    (cond ((empty? L2) L2) 
      ((equal? (car L2) L1) (elimina L1 (cdr L2))) 
      (else (concatena (list (car L2)) (elimina L1 (cdr L2)))) 
    ) 
) 

私のアプローチ:

(define (repetidos L1) 
    repetidos-recorre(L1 '()) 
) 
(define (repetidos-recorre(L1 acc)) 
    (if (null? (cdr L1)) 
     (concatena(list(car L1) acc)) 
     (concatena ((car L1) (cons(elimina(list((car L1) acc)))))) 
    ) 
) 

私は、実際の解析された要素がすでに私は機能開発累積1上に存在するかどうかを知るためにいくつかの方法を使用する必要があり実現したよう:

(define (miembro L X) 
    (if (null? L) 
     #f 
     (if (eq? (car L) X) 
      #t 
      (miembro (cdr L) X) 
     ) 
    ) 
) 

を私は大体試した:

(define (repetidos L) 
    (repetidos-recorre L '() 
    ) 
) 
(define (repetidos-recorre L acumulado) 
    (if (null? L) 
     acumulado 
     (if (miembro acumulado (car L)) 
      (repetidos-recorre (cdr L) (concatena (elimina (car L) acumulado) (car L) ) )) 
      (repetidos-recorre (cdr L) (concatena (car L) acumulado)) 
    ) 
) 

そして、私は終わりました私がこのコードが誤動作していることを知っているので私が立ち往生しているところでは、私はそれらの2つの繰り返し機能をテストしていないためです。私は助手のすべてが正しく機能していることを知っていますが、私はそれらを理解しましたが、私はこの最後の課題を解決するために、あるいは少なくともこの問題を解決する方法を教えてくれました。あなたの時間をありがとう!

+0

こんにちは私には、「すべての繰り返された要素が最後のものを除いて消えている」ということを私には完全にはっきりさせていません。関数の振る舞いを示すいくつかの例を追加できますか? –

+0

ランまたはすべての要素を削除します。例えば。 ''(1 a 2 a) 'のリストの結果はどうなりますか? '(1 a 2 a)'または '(1 2 a)'ですか? – Sylwester

答えて

0

miembroが正しく実装されていると仮定すると、eliminaまたはconcatenaを使用する必要はありません。より良いアプローチは、次のようになります。代わりに、ネストifのも

(define (repetidos L) 
    (repetidos-recorre L '())) 

(define (repetidos-recorre L acumulado) 
    (if (null? L) 
     acumulado 
     (if (miembro acumulado (car L)) 
      (repetidos-recorre (cdr L) acumulado) 
      (repetidos-recorre (cdr L) (cons (car L) acumulado))))) 

を、それが単一condを使用することをお勧めしますよ、今の-であるように私はそれを残しておきます。これは、それがどのように動作するかです:要素は逆の順序で表示され

(repetidos '(1 a a 2 a)) 
=> '(2 a 1) 
(repetidos '(1 a 2 a)) 
=> '(2 a 1) 
(repetidos '(1 2 a)) 
=> (repetidos '(1 2 a)) 

お知らせすることを、我々はリストの先頭にcons ING要素だからそれはです。あなたが見ることができるように

(define (repetidos-recorre L acumulado) 
    (if (null? L) 
     acumulado 
     (if (miembro acumulado (car L)) 
      (repetidos-recorre (cdr L) acumulado) 
      (repetidos-recorre (cdr L) (concatena acumulado (list (car L))))))) 

、順序が保存されています:順序が重要ならば、我々は少なく、効率的な解決策になるだろうことを念頭に置いてconcatenaを使用していますが、負担する必要があり

(repetidos '(1 a a 2 a)) 
=> '(1 a 2) 
(repetidos '(1 a 2 a)) 
=> '(1 a 2) 
(repetidos '(1 2 a)) 
=> '(1 2 a) 
+0

オスカー・ロペスに感謝しています。私はあなたの解決策を理解しました。私が思っていた以上に簡単でした。最後に私はそれをキャッチし、あなたは私を助けた! – Enoy

関連する問題