1

[_、[X、_]、_]は[d、[X、a]、s]のようなリストに一致します。1つ以上の匿名変数があるパターンに一致させる方法はありますか?すなわち。[[X、a]、s]と[[d、a]、[p、z]、[X、b]]は一致しますか?

リスト内の要素を数えるプログラムを書こうとしています。[a、a、a、b、a、b] => [[a、4]、[b、2]]しかし、私は立ち往生しています:

listcount(L, N) :-  listcountA(LS, [], N).
listcountA([X|Tail], [? [X, B], ?], N) :- B is B+1, listcountA(Tail, [? [X,B] ?], N).
listcountA([X|Tail], AL, N) :- listcountA(Tail, [[X,0]|AL], N).

ありがとう。

4

3 に答える 3

2

変数はtermに一致し、anonimus 変数も例外ではありません。リストは、頭と尾の間の二項関係の単なる構文糖衣です。したがって、変数はリスト、ヘッド、またはテールに一致できますが、未指定のシーケンスには一致しません。

役立つことを願っています。

listcount(L, N) :- listcountA(LS, [], N).

Prolog では、述語は名前num.of.arguments (ファンクターアリティと呼ばれる) で識別されます。したがって、通常、引数が追加された「サービス」述語は同じ名前を保持します。

listcountA([X|Tail], [? [X, B], ?], N) :- B は​​ B+1、listcountA(Tail, [? [X,B] ?], N)。

B is B+1 は成功しません。新しい変数を使用する必要があります。そして、あなたがしているように、「ワイルドカード」を使用してリスト内で一致させる方法はありません。代わりに、カウンターを見つけて更新する述語を記述します。

最後の注意: 通常、要素のペアは、便利な (任意の) 演算子である二項関係を使用して示されます。たとえば、最もよく使用されるのはダッシュです。

だから私は書くだろう

listcount(L, Counters) :-
    listcount(L, [], Counters).

listcount([X | Tail], Counted, Counters) :-
    update(X, Counted, Updated),
    !, listcount(Tail, Updated, Counters).
listcount([], Counters, Counters).

update(X, [X - C | R], [X - S | R]) :-
    S is C + 1.
update(X, [H | T], [H | R]) :-
    update(X, T, R).
update(X, [], [X - 1]).  % X just inserted

update/3 は、再帰の「内側に移動」するライブラリ述語を使用して簡略化できます。たとえば、select/3 を使用すると、次のようになります。

listcount([X | Tail], Counted, Counters) :-
    ( select(X - C, Counted, Without)
    ->  S is C + 1
    ;   S = 1, Without = Counted
    ),
    listcount(Tail, [X - S | Without], Counters).
listcount([], Counters, Counters).
于 2012-03-19T23:49:08.143 に答える
1

この回答が気に入った場合は、@chac に正しい回答を与えることを検討してください。この回答は彼らの回答に基づいているためです。

アキュムレータも使用し、入力リストの変数を処理するバージョンを次に示します。これにより、直接要求した出力用語構造が得られます。

listcount(L, C) :-
    listcount(L, [], C).
listcount([], PL, PL).
listcount([X|Xs], Acc, L) :-
    select([X0,C], Acc, RAcc), 
    X == X0, !,
    NewC is C + 1,
    listcount(Xs, [[X0, NewC]|RAcc], L).
listcount([X|Xs], Acc, L) :-
    listcount(Xs, [[X, 1]|Acc], L).

listcount/2アキュムレータにカウントを維持するアキュムレータベースのバージョンに従いlistcount/3、入力順序またはグラウンド入力リストを想定していないことに注意してください(名前付き/ラベル付き変数は正常に機能します)。

于 2012-03-20T01:31:18.163 に答える
0

[_, [X, _], _] は、3 つの要素を持つリストのみに一致します。1 番目と 3 番目はアトムまたはリストにすることができ、2 番目の要素は長さ 2 のリストでなければなりませんが、それを知っていると思います。2 つの要素リストには一致しません。要素を見つけて結果リストに挿入するには、先頭から末尾への再帰を使用することをお勧めします。ここに述語のスケッチがありますが、コピーして貼り付けるとうまくいかないでしょう;)

% find_and_inc(+element_to_search, +list_to_search, ?result_list)
find_and_inc(E, [], [[E, 1]]);
find_and_inc(E, [[E,C]|T1], [[E,C1]|T2]) :- C1 is C+1;
find_and_inc(E, [[K,C]|T1], [[K,C]|T2]) :- find_and_inc(E, T1, T2).
于 2012-03-19T22:53:26.767 に答える