1

リストから要素を削除したいのですが、これを行うと:

deletelist([3,1,2,3,4], [3], [3,1,2,4]) 

3だけを削除してこの答えを得ない方法:

deletelist([3,1,2,3,4], [3], [1,2,4])

ありがとう!

4

2 に答える 2

2

select /3 これは便利な組み込みで、頻繁に使用されgenerate and test、要素を削除するために使用できます。

?- select(3,[3,1,2,3,4],L).
L = [1, 2, 3, 4] ;
L = [3, 1, 2, 4] ;
false.

呼び出しごとに一致が削除されるため、目的の動作を制御できます

編集

2 番目のリストからすべての要素を削除するには:

deletelist(L, [], L).
deletelist(With, [D|Ds], Without) :-
    select(D, With, WithoutD),
    deletelist(WithoutD, Ds, Without).

削除する要素のいずれかがリストに見つからない場合、これは失敗することに注意してください。これを回避するには、「if .. then .. else ..」を適用します。

deletelist(L, [], L).
deletelist(With, [D|Ds], Without) :-
    (  select(D, With, WithoutD)
    -> deletelist(WithoutD, Ds, Without)
    ;  deletelist(With, Ds, Without)
    ).

現在、deletelist/3 は可能なすべての削除を列挙しません。最初に見つかったものにコミットします。すべての異なる削除をバックトラックする最初の動作を再開するには、効率の低い手順が必要です。

deletelist(L, [], L).
deletelist(With, [D|Ds], Without) :-
    select(D, With, WithoutD),
    deletelist(WithoutD, Ds, Without).
deletelist(With, [D|Ds], Without) :-
    \+ select(D, With, _),
    deletelist(With, Ds, Without).
于 2013-01-22T11:55:03.857 に答える
1

リスト内の一意の値だけを取得したい場合は、関数list_to_set/2を使用します:

list_to_set([3,1,2,3,4],X)与えるX = [3, 1, 2, 4].

編集:

そのgnu prologため、組み込みの述語はありませんlist_to_set。自分で書く必要があります。このためには、セットの概念を定義する必要があります。とはset of list? セットには次の属性が必要です。

  • セットのサイズは、リストのサイズ以下にする必要があります。
  • Set のすべてのメンバーは、List のメンバーでなければなりません。
  • List のすべてのメンバーは、Set のメンバーでなければなりません。
  • セットに重複した値を含めてはなりません。

これらの仮定に基づいて、次のようにset_from_list述語を記述できます。

elem_unique(Elem, List) :-
  delete(List, Elem, ListWithoutElem),
  length(List, OrgLength),
  length(ListWithoutElem, DelLength),
  DelLength + 1 =:= OrgLength.

nth_elem_isUnique(N, List) :-
  nth1(N, List, Elem),
  elem_unique(Elem, List).

nth_elemOfList1_isMemberOfList2(N, List1, List2) :-
  nth1(N, List1, Elem),
  member(Elem, List2).

elements_from_nth_areUnique(N, List) :-
  (length(List, Len),
  N > Len)    %stoping condition for recursion
  ;
  (nth_elem_isUnique(N, List),
  M is N + 1,
  elements_from_nth_areUnique(M, List)   %recursion part
  ).

listIsUnique(List) :-
  elements_from_nth_areUnique(1, List).

elements_from_nth_inList1_areMembersOfList2(N, List1, List2) :-
  (length(List1, Len),
  N > Len)    %stoping condition for recursion
  ;
  (nth_elemOfList1_isMemberOfList2(N, List1, List2),
  M is N + 1,
  elements_from_nth_inList1_areMembersOfList2(M, List1, List2)  %recursion part
  ).

list2containsList1(List1, List2) :-
  elements_from_nth_inList1_areMembersOfList2(1, List1, List2).

set_from_list(Set, List) :-
  length(Set, LenSet),
  length(List, LenList),
  LenSet =< LenList,
  list2containsList1(List, Set),
  list2containsList1(Set, List),
  listIsUnique(Set),
  !.

したがって、電話した後、が表示set_from_list(Set, [3,1,2,3,4])されますSet = [3,1,2,4]

于 2013-01-22T11:01:26.080 に答える