试图弄清楚,如何在Prolog中合并像这样的输出:
[[z], [l, e, d], [j, i, d, c, a], [g, f, b], [h, b]]
获得结果:
[z]
[l,e,d,j,i,c,a]
[g,f,b,h]
不确定如何合并包含至少一个相似字符的多个列表。
我会感谢更有经验的人提供的任何帮助,因为我只是初学者而且这项任务非常棘手。
感谢。
修改
任务是从用户定义的边缘获取所有连接的组件并在输出上打印它们。
例如用户输入边缘:
data([[z,z],[a,c],[c,d],[d,i],[i,j],[d,e],[e,l],[b,f],[f,g],[b,h]]).
所以我想弄明白如何解决这个问题。 我刚刚做了什么:
data(Edges):-
dbH(Edges),
searching,
print,
retractall(e(_,_)),
retractall(lists(_)).
dbH([]).
dbH([[X, Y] | Body ]) :-
assertz(e(X,Y)),
dbH(Body).
oe(X,Y):-
e(X,Y);
e(Y,X).
searching:-
nextE.
searching([Act | RouteStartAct]):-
nextE([Act | RouteStartAct]).
nextE:-
oe(Act,New),!,
delE(Act,New),
cycle([Act],New).
nextE:-
!.
nextE([Act | RouteStartAct]):-
oe(Act,New),!,
delE(Act,New),
cycle([Act | RouteStartAct],New).
nextE(Act):-
assertz(lists(Act)),
searching.
delE(X,Y):-
retract(e(X,Y));
retract(e(Y,X)).
cycle(Act,New):-
not(mbr(New, Act)), !,
searching([New|Act]).
cycle(Act,New):-
assertz(lists(Act)),
searching.
mbr(Element, [Element|_]).
mbr(Element, [_|Body]) :-
mbr(Element, Body).
print:-
findall(C,lists(C),L),
write(L).
最后,write(L)打印列表列表,我需要根据每个列表中的类似元素进一步合并。就像将一个图形的各个部分连接在一起并打印出来一样。
EDIT2 该命令的结果:
?- data([[a, c], [c, d], [d, i], [i, j], [d, e], [e, l], [b, f], [f, g], [b, h]]).
是
[[j, i, d, c, a], [l, e, d], [g, f, b], [h, b]]
所以从这个输出很明显,列表[j, i, d, c, a]
和[l, e, d]
可以合并到一个列表[j, i, d, c, a, l, e]
中。对于列表[g, f, b]
和[h, b]
,这两个列表的共同字符b
相同,因此输出应为[g, f, b, h]
。
由于这两个合并,最终输出应如下所示:
[j, i, d, c, a, l, e]
[g, f, b, h]
知道更明显吗?
答案 0 :(得分:1)
你可以从
开始touching(A,B):- memberchk(E,A), memberchk(E,B).
joined(A,B,C):- touching(A,B), setof(X, (member(X,A) ; member(X,B)), C).
现在,您将完成一个步骤关系的任务,该步骤关系将找到任意给定列表中touching/2
成功的两个成员,并使用新的{{}更新列表1}}进入;并重复此步骤,直到它不能再执行;从而得出解决方案。
答案 1 :(得分:0)
@WillNess嗨嗨,我已经花了一天时间尝试实施你的提示,但不幸的是我无法重新设计你的来源以便为我的情况正常工作。特别是当我需要使用递归来操作所有列表时,我遇到了情况,如果我发现两个列表至少有一个相似的元素,我可以通过setof函数将它们连接在一起,并继续使用这个新列表来比较其余部分。然而,前两个列表没有任何类似的元素?举个例子:[[a,b,c,d], [e,f,g],[i,j,k],[e,a,b]]
。在这种情况下,如果我尝试比较列表[a,b,c,d]
和[e,f,g]
,那么我无法将这两个列表连接在一起,因为它们没有任何相似的字符。但在连接[a,b,c,d]
和[e,a,b]
后的最后,我还能够连接第一种情况[a,b,c,d]
和[e,f,g]
。你能看出我的观点吗?我需要以某种方式从一种方式和后一种方式进行迭代。这种情况对我来说绝对是死路一条。想知道我的主要目标是否有更好的解决方案,即根据用户插入的边缘打印断开连接图的所有部分。