繁体   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