簡體   English   中英

友好列表序言

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

我假設友好的定義意味着列表處於“鎖定步驟”之外的兩個最大差異之內。

順序重要嗎? 列表 (每個元素是唯一的)還是包裝袋 (允許重復)?

假如說

  • 順序無關緊要([1,2,3]和[1,3,2]被視為相同),並且
  • 重復無關緊要([1,2,3,1]和[1,2,3])被視為相同

這樣的事情可能與您要查找的內容類似:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM