List Prolog-将过程应用于特定列表成员

List Prolog-将过程应用于特定列表成员,list,prolog,nested,List,Prolog,Nested,我有一个函数,它接受一个列表,并删除该列表中所有唯一的元素: repeating(Q, L):- repeating(Q, Q, L). repeating([], _, []). repeating([H | T], Q, [H | L]):- count(H, Q, N), N > 1, !, repeating(T, Q, L). repeating([H | T], Q, L):- count(H,

我有一个函数,它接受一个列表,并删除该列表中所有唯一的元素:

repeating(Q, L):-
        repeating(Q, Q, L).
repeating([], _, []).
repeating([H | T], Q, [H | L]):-
        count(H, Q, N),
         N > 1, !,
        repeating(T, Q, L).
repeating([H | T], Q, L):-
        count(H, Q, N),
        N = 1,
        repeating(T, Q, L).
例如查询

 repeating([1, 2, 3, 4, 5, 2, 7, 7, 3, 8], X). 
给予

 X = [2, 3, 2, 7, 7, 3]. 
我想将其应用于由四个元素的长列表组成的列表,只检查第三个元素,例如

   repeating([[1, 2, 3, 4], [5, 6, 7, 8], [3, 5, 7, 9], [4, 3, 2, 1]], X).
会回来吗

   X = [[5, 6, 7, 8], [3, 5, 7, 9].
仅包含非唯一第三个元素的列表。我的代码现在只适用于简单的列表,比如第一个列表,我花了一个上午的时间试图找到一种方法来修改它,使其适用于任意长的四元素长列表的情况,但是还没有找到这样做的方法,我非常希望得到一些指导


谢谢。

您可以获得一个函数来检索每个列表的第三个元素,然后通过检查这些元素来调整代码

%get the third element of a list
third([_,_,E|_], E).

%Build a list made of the third elements of the input list
buildthirdslist([],[]).
buildthirdslist([X|Xl],[Th|Thl]):-
    third(X,Th),
    buildthirdslist(Xl,Thl).


%Your code adapted
repeatingthirds(Q, L):-
    buildthirdslist(Q,Ths),
        repeatingthirds(Q, Ths, L).

repeatingthirds([], _, []).

repeatingthirds([H | T], Q, [H | L]):-
    third(H,Th),
        count(Th, Q, N),
         N > 1, !,
        repeatingthirds(T, Q, L).

repeatingthirds([H | T], Q, L):-
    third(H,Th),
        count(Th, Q, N),
        N = 1,
        repeatingthirds(T, Q, L).

只是吉列尔莫解的一点变化。这一步使您的
重复
谓词保持不变,并使用不同的
计数

repeating(Q, L):-
        repeating(Q, Q, L).
repeating([], _, []).
repeating([H | T], Q, [H | L]):-
        count(H, Q, N),
        N > 1, !,
        repeating(T, Q, L).
repeating([H | T], Q, L):-
        count(H, Q, N),
        N = 1,
        repeating(T, Q, L).

count(H, Q, N) :-
    count(H, Q, 0, N).
count([_,_,E,_], [[_,_,E,_]|T], A, N) :-
    A1 is A + 1,
    count([_,_,E,_], T, A1, N).
count([_,_,E,_], [[_,_,X,_]|T], A, N) :-
    E \= X,
    count([_,_,E,_], T, A, N).
count(_, [], A, A).
快速测试:

| ?- repeating([[1, 2, 3, 4], [5, 6, 7, 8], [3, 5, 7, 9], [4, 3, 2, 1]], X).

X = [[5,6,7,8],[3,5,7,9]] ? a

no

|?-

此更改将影响
计数
,但可能根本不会影响
重复
。在
count
中,将正在计数的元素视为
[\uu,\uu,X,\u]
,并对匹配的第三个元素进行计数<代码>重复,我认为,可能会保持不变,因为它不会将您的列表限制为原子元素。这绝对是非常棒的,我一读它就印象深刻。它非常简单,完全符合我的要求,甚至我也能够阅读代码,轻松理解正在发生的事情。非常感谢你。