[英]Friendly lists prolog
我给了2个列表,例如K=[a,b,c,d,e,f,g]
和L=[a,b,1,d,e,2,g]
。 当这两个列表具有2个不同的元素时,它们是友好的。
这是我尝试过的:
friendly(K,L):-
append(L1,[Z],A1),
append(A1,L2,A2),
append(A2,[Q],A3),
append(A3,L3,K),
append(L1,[Y],B1),
append(B1,L2,B2),
append(B2,[W],B3),
append(B3,L3,L),
Z\=Y,
Q\=W.
非常感谢,终于找到了正确的代码:
friend(L1,L2):-
append(A,Y,L1),
append([Z|T],[F|TT],Y),
append(A,Q,L2),
append([R|T],[O|TT],Q),
Z\=R,
F\=O.
做下面的事情会更好吗?
diff([], [], []).
diff([], K, K).
diff(L, [], L).
diff([H | TL], [H | TK], D) :- diff(TL, TK, D),!.
diff([HL | TL], [HK | TK], [HL, HK | D]) :- diff(TL, TK, D),!.
friendly(K, L) :- diff(K, L, D), length(D, Length), Length < 3.
但是您的问题确实没有得到充分说明。 例如,我的程序确实关心顺序,因此按我的定义[a,x,b]
和[a,b]
不友好。
您可以通过这种方式使用append / 3来查找前几个不同的元素。
first_different(L1,L2, R1,R2) :-
append(H, [E1|R1], L1),
append(H, [E2|R2], L2),
E1 \= E2.
H是公共部分,R1,R2是“余数”。 该代码与您在上面的第二条注释更加一致。
现在,您必须两次应用此辅助谓词,并且第二次“余数”必须相等,或者其中之一必须为空。 那是
friendly(L1,L2) :-
first_different(L1,L2,R1,R2),
first_different(R1,R2,T1,T2),
once((T1=T2;T1=[];T2=[])).
另外,使用一些内置函数可能会有所收获。 这应该工作
friendly(L1,L2) :- findall(_,(nth1(I,L1,E1),nth1(I,L2,E2),E1\=E2),[_,_]).
对于“友好”列表的总定义,我仍然不确定,但是我认为这可能会回答:
friendly(A, B) :-
friendly(A, B, 2).
friendly([H|TA], [H|TB], C) :-
C > 0,
friendly(TA, TB, C).
friendly([HA|TA], [HB|TB], C) :-
HA \= HB,
C > 0,
C1 is C-1,
friendly(TA, TB, C1).
friendly(A, [], C) :-
length(A, L),
L =< C.
friendly([], B, C) :-
length(B, L),
L =< C.
friendly(A, A, 0).
我假设友好的定义意味着列表处于“锁定步骤”之外的两个最大差异之内。
顺序重要吗? 列表集 (每个元素是唯一的)还是包装袋 (允许重复)?
假如说
这样的事情可能与您要查找的内容类似:
friendly(Xs,Ys) :-
set_of(
E ,
(
( member(E,Xs) ,
not( member(E,Ys) )
)
;
(
member(E,Ys) ,
not( member(E,Xs) )
) ,
Zs
) ,
length( Zs , L ) ,
L =< 2
.
查找每个列表中彼此不在的所有元素的集合,如果结果列表的长度为0、1或2,则成功。
我想出了一些与其他类似的东西。.我只保留一个“ _”项列表(diff_list的最终参数)-每个差异一个,就是相同索引的值差异或长度差异,然后最终在friendly / 2中,检查是否有2个项目。
% recursion base
diff_list([], [], []).
% the head of both lists are the same, don't add to diff list
diff_list([HK|TK], [HK|TL], Diff) :-
diff_list(TK, TL, Diff).
% the above rule failed, so must be a difference, add a '_'
diff_list([_|TK], [_|TL], [_|Diff]) :-
diff_list(TK, TL, Diff).
% 1st list is empty, but the 2nd isn't. That's a diff again.
diff_list([], [_|TL], [_|Diff]) :-
diff_list([], TL, Diff).
% 2nd list is empty, but the 1st isn't. Another diff.
diff_list([_|TK], [], [_|Diff]) :-
diff_list(TK, [], Diff).
% friendly is true if the diff list length unifies with 2 item length list [_,_]
friendly(K, L) :-
diff_list(K, L, [_,_]).
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.