24

X = [1、2、3、4]などのリストがPrologにある場合、リストの最後に要素5を追加してX = [1、2、3、4、5]にする方法を教えてください。

append関数には、AとBをリストCに連結するために、2つのリスト、つまりappend(A、B、C)が必要です。

一時リストY=[1、2、3、4]およびZ = [5]を使用してこれを実行し、次にappend(Y、Z、X)を実行できますが、一時リストを作成するのは好きではありません。

通常の免責事項がここに適用されます-これは宿題ではなく、私はPrologを学んでいます。

4

6 に答える 6

12

他の人が指摘しているように、あなたはパフォーマンスの問題で立ち往生するでしょう。
しかし、演習と同じように、を使用せずにリストの最後に要素を追加できる述語を作成することにしましたappend

% add_tail(+List,+Element,-List)
% Add the given element to the end of the list, without using the "append" predicate.
add_tail([],X,[X]).
add_tail([H|T],X,[H|L]):-add_tail(T,X,L).

append組み込み関数として、手動で作成したものよりも高速である可能性が高いため、この関数を使用することをお勧めします。

于 2014-09-13T19:37:21.607 に答える
11

Prologの変数は一度だけ割り当てることができます。Xの値が[1,2,3,4]になるとすぐに、別の値を持つことはできなくなります。あなたが言ったように、一時変数とappend/3はそれを行う方法です。

そうは言っても、おそらくお勧めできない1つのトリックを実行できます。X = [1,2,3,4、Y]の場合、Y = 5を実行でき、Xは必要な値になります。このテクニックは差分リストと呼ばれていると思います。

于 2013-02-23T06:29:08.467 に答える
3

宣言型の解決策の1つは、差分リストを使用することです(Danielがその回答で示唆したように)。差分リストの名前は、通常、リストとその末尾の2つのリストの差分として表されることから付けられます。たとえば、空のリストはとして表すことができますT-T。要素1、2、および3を含むリストは、次のように表すことができます(これは標準の組み込み中置演算子であることに[1,2,3| T]-T注意してください)。(-)/2この表現の利点は、append/3述語の単一のファクト定義を使用して、一定時間内に要素をリストに追加できることです。

append(L1-T1, T1-T2, L1-T2).

使用例:

?- append([1,2,3,4| T1]-T1, [5| T2]-T2, Result).
T1 = [5|T2],
Result = [1, 2, 3, 4, 5|T2]-T2.

必要に応じて、「通常の」リストと差分リストの間で変換することは難しくありません。私はそれをあなたに練習として任せます。

于 2014-09-13T21:14:21.863 に答える
3

Prologでリストを変更することはできませんが、長さが指定されていないリストを作成することはできます。

main :-
    A = [1,2,3,4|_].

nth0/3次に、 SWI-Prologを使用して要素を挿入できます。

:- initialization(main).

main :-
    A = [1,2,3,4|_],
    nth0(4,A,5),
    writeln(A).

この要素が挿入された後、A = [1,2,3,4,5|_]

リストの最後にアイテムをインプレースで追加する関数を定義して、次のように使用することもできます。

:- initialization(main).

append_to_list(List,Item) :-
    List = [Start|[To_add|Rest]],
    nonvar(Start),
    (var(To_add),To_add=Item;append_to_list([To_add|Rest],Item)).

main :-
    A = [1,2,3|_],
    append_to_list(A,4),
    append_to_list(A,4),
    writeln(A).

この例ではA = [1,2,3,4,4|_]、これら2つの項目の後に追加されます。

于 2018-02-06T03:28:03.283 に答える
3

Prologにはリストのみを受け入れるappendがあるので、それを使用してリストの1つに要素を挿入してみませんか。すなわち

% E = element, L = list, R = result
% e.g. add_elem_in_list ([1,2,3,4], 5, R).
add_elem_in_list(L, E, R) :- append(L, [E], R).
于 2018-02-12T13:16:31.730 に答える
2

あなたは問題の間違った終わりを心配しています。構造の共有は、リストの先頭に要素を配置することによってのみ発生します。その方法には、必要なパフォーマンス特性があります。リストの定義方法により、2つのリストを追加すると、最初のリスト全体がコピーされます。この場合、それがリスト全体になります。1つのアイテムのリストによって生成されるガベージは、明らかにそれよりもはるかに小さくなります。

本当に追加する必要がある場合は、リストを逆方向に作成してから、最後に1回逆にすることを検討してください。これははるかに安価です。または、差分リストを使用して、最後に効率的に追加できるようにします。

于 2013-02-22T16:45:23.427 に答える