[英]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.