简体   繁体   English

友好列表序言

[英]Friendly lists prolog

I am given 2 lists for example K=[a,b,c,d,e,f,g] and L=[a,b,1,d,e,2,g] . 我给了2个列表,例如K=[a,b,c,d,e,f,g]L=[a,b,1,d,e,2,g] When these 2 lists have 2 different elements, then they are friendly. 当这两个列表具有2个不同的元素时,它们是友好的。

This is what I've tried: 这是我尝试过的:

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.

Thank you all so much, at last I found the correct code: 非常感谢,终于找到了正确的代码:

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.

Wouldn't it be better to do something like the following? 做下面的事情会更好吗?

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.

But your problem really is underspecified. 但是您的问题确实没有得到充分说明。 For example my program really cares about order so [a,x,b] and [a,b] are not friendly by my definition. 例如,我的程序确实关心顺序,因此按我的定义[a,x,b][a,b]不友好。

You can use append/3 in this way to locate the first different elements. 您可以通过这种方式使用append / 3来查找前几个不同的元素。

first_different(L1,L2, R1,R2) :-
  append(H, [E1|R1], L1),
  append(H, [E2|R2], L2),
  E1 \= E2.

H is the common part, R1,R2 are the 'remainders'. H是公共部分,R1,R2是“余数”。 This code is more in line with your second comment above. 该代码与您在上面的第二条注释更加一致。

Now you must apply two times this helper predicate, and the second time also 'remainders' must be equal, or one of them must be empty. 现在,您必须两次应用此辅助谓词,并且第二次“余数”必须相等,或者其中之一必须为空。 That is 那是

friendly(L1,L2) :-
  first_different(L1,L2,R1,R2),
  first_different(R1,R2,T1,T2),
  once((T1=T2;T1=[];T2=[])).

Alternatively, using some builtin can be rewarding. 另外,使用一些内置函数可能会有所收获。 This should work 这应该工作

friendly(L1,L2) :- findall(_,(nth1(I,L1,E1),nth1(I,L2,E2),E1\=E2),[_,_]).

I'm still a little uncertain about the total definition of "friendly" list, but I think this might answer it: 对于“友好”列表的总定义,我仍然不确定,但是我认为这可能会回答:

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).

I'm assuming that the definition of friendly means the lists are in "lock step" outside of the maximum of two differences. 我假设友好的定义意味着列表处于“锁定步骤”之外的两个最大差异之内。

Does order matter? 顺序重要吗? Are the lists sets (each element is unique) or bags (duplicates allowed)? 列表 (每个元素是唯一的)还是包装袋 (允许重复)?

Assuming that 假如说

  • Order doesn't matter ([1,2,3] and [1,3,2]) are treated as identical), and 顺序无关紧要([1,2,3]和[1,3,2]被视为相同),并且
  • Duplicates don't matter ([1,2,3,1] and [1,2,3]) are treated as identical 重复无关紧要([1,2,3,1]和[1,2,3])被视为相同

Something like this might be along the lines of what you're looking for: 这样的事情可能与您要查找的内容类似:

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
    .

Find the set of all elements of each list that aren't in the other and succeed if the resulting list is of length 0, 1 or 2. 查找每个列表中彼此不在的所有元素的集合,如果结果列表的长度为0、1或2,则成功。

I came up with something similar to others.. I just keep a list of '_' items (final param of diff_list) - one for each difference, be that a value difference at the same index, or a difference in the length, then finally in friendly/2, check that has 2 items. 我想出了一些与其他类似的东西。.我只保留一个“ _”项列表(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