2016-05-22 11 views
3

リスト要素の連続する重複を除去する。連続する重複を除去する

このため私のソリューションは、次のとおりです。

compress([X,X|Xs], Q) :- 
    compress([X|Xs], Q). 
compress([X,Y|Xs], Q) :- 
    X \= Y, 
    compress([Y|Xs], QR), 
    append([X], QR, Q). 
compress([X|[]], Q) :- 
    compress([], QR), 
    append([X], QR, Q). 
compress([], []). 

そして、理由は事実を私は初心者です、私は、論理パラダイムで経験がない私はをお願いし、私が改善することができるかと言うと、なぜ私の解決策ではありませんそれができるように良い。

たとえば、X \= Yはわかりません。

答えて

5

まず、述語のという名前のから始めます。

なぜの必須のを使用しての関係を指定していますか?良いPrologプログラムはすべて 方向で使用できますが、命令は常に特定の方向または使用方法を示唆します。したがって、宣言的な という名前をと選択し、一般性とを目指してください。

次に、どのような最も一般的なクエリについて:

?- compress(Ls, Cs). 
ERROR: Out of local stack 

ない非常に素晴らしいです!これにより、少なくともいくつかの回答が得られると期待しています。

私たちは、反復深化を使用する場合:

 
?- length(Ls, _), compress(Ls, Cs). 
Ls = Cs, Cs = [] ; 
Ls = Cs, Cs = [_G841] ; 
Ls = [_G841, _G841], 
Cs = [_G841] ; 
Ls = [_G841, _G841, _G841], 
Cs = [_G841] . 

フムを!かなりの答えがありません!要素がと異なる場合はどうですか??すでに直観的に期待しているように、そのような影響をもたらすのは不潔な述語の使用です。

したがって、2つの用語は異なるあることを示すために、、即ち、dif/2を使用します。それはすべての の指示に使用可能です!

また、リストを記述するときにDCG()が便利な場合があります。

ので、トータルでは、何これについて:

 
compression([])  --> []. 
compression([L|Ls]) --> [L], compression_(Ls, L). 

compression_([], _) --> []. 
compression_([X|Xs], L) --> 
     ( { X = L }, 
      compression_(Xs, L) 
     ; { dif(X, L) }, 
      [X], 
      compression_(Xs, X) 
     ). 

我々はDCGで動作するようにインターフェイス述語phrase/2を使用しています。

使用例:

 
?- phrase(compression(Ls), Cs). 
Ls = Cs, Cs = [] ; 
Ls = Cs, Cs = [_G815] ; 
Ls = [_G815, _G815], 
Cs = [_G815] . 

?- length(Ls, _), phrase(compression(Ls), Cs). 
Ls = Cs, Cs = [] ; 
Ls = Cs, Cs = [_G865] ; 
Ls = [_G865, _G865], 
Cs = [_G865] ; 
Ls = Cs, Cs = [_G1111, _G1114], 
dif(_G1114, _G1111) . 

はここからそれを持っていこう!決定論を改善し、より良い名前などを見つける

+0

!それは進歩を意味するので、それは非常に良い情報です! :)。 "したがって、2つの用語が異なることを示すために、prolog-dif、すなわちdif/2を使用してください。すべての方向で使用可能です! なぜ '\ ='の代わりに 'dif/2'を使うべきなのか分からないのですか?特に、*方向*を強調表示します。私がそれを得ることができないので、あなたは正確に何を意味しますか? 。 – Gilgamesz

+0

'"長さ(LS、_)、圧縮(LS、Cs等) Lsは=セシウム、セシウム= []; Lsは=セシウム、セシウム= [_G841]; のLS = [_G841、_G841]、 のCs = [_G841]; Ls = [_G841、_G841、_G841]、 Cs = [_G841]。 "。あなたはそのコードの中で私に何を見せたいのですか? :) – Gilgamesz

+0

「それほどうれしいことではありません!私たちはこれが少なくともいくつかの答えを出すと期待しています。 イデッド、そうです。しかし、ここで期待される行動は何ですか?結局のところ、 'compress(Ls、Cs)' 'Ls'はリストではないので、未定義の動作(yes、私はC++でプログラミングしています))でなければなりません) – Gilgamesz

4

the answer by @matのビル(1)、なぜはこのようなケースで決定性改善されない:SWI ; false

 
?- phrase(compression([a,a,b,b,b,c,c,c,c,d]), Xs). 
Xs = [a, b, c, d]; 
false. 

は目標が確定的に成功しなかったことを示しています。

我々はif_//3 —を使用してcompression_//2を向上させることができますif_/3アナログ:

 
compression_([], _) --> []. 
compression_([X|Xs], L) --> 
 if_ (X  = L,       % is this item equal to previous one? 
     compression_(Xs, L),    % yes: old "run" goes on 
     ([X], compression_(Xs, X))).  % no: new "run" starts 

サンプルクエリ:あなたは私の頭の中でめちゃめちゃ

?- phrase(compression([a,a,b,b,b,c,c,c,c,d]), Xs). 
Xs = [a, b, c, d].       % succeeds deterministically 
関連する問題