2017-02-02 5 views
1

Пытаясь понять это, как я могу объединить выход как этот в Прологе:Объединение нескольких списков, содержащих тот же элемент в 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] 

Не знаете, как объединить несколько списков, содержащих хотя бы один похожий символ.

Буду признателен за помощь более опытных парней, потому что я только начинаю, и эта задача довольно сложная.

Спасибо.

EDIT

задача получить от краев, определенных пользователем всех подключенных компонентов и распечатать их на выходе.

Для ввода пользователя экземпляра края:

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

В конце записи (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] 

Это более очевидно, знаете?

+2

Вам нужно показать, что вы пробовали, даже если не работает, и объясните, что вы намеревались сделать, и что он сделал вместо этого. Вопросы без этого обычно не получают ответов. Другими словами, это похоже на проблему домашней работы, и большинство людей не дает ответов на домашнюю работу, только помощь. –

+0

Спасибо за ответ, ты прав. Что я могу сделать, так это сравнить два списка (A и B), и если в списке B есть один похожий символ в списке B, то я могу объединить эти два списка вместе, но что, если соединение вообще отсутствует? Оставьте их такими, какие они есть, но что, если есть еще 10 списков для сравнения? Множество списков сложной ситуации для меня ... –

+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 преуспевает, и обновить список с новый joined/3 запись; и повторите этот шаг, пока он больше не будет выполнен; таким образом, достигнув решения.

+0

Мне очень нравится использование 'setof/3' здесь! s (X) –

+0

Выглядит отлично, мне нужно немного отредактировать вам совет и добавить некоторые вещи, но надеюсь, что он решает мою проблему. Большое спасибо !!! –

+0

@ DanielLyons Я попробовал все остальное первым, хотя. :) По какой-то причине это не сработало. (bagof не удалял дубликаты ... не понимаю почему). –

0

@WillNess Hi again Will, я потратил еще один день, пытаясь реализовать свой намек на мою ситуацию, но, к сожалению, я не могу переработать ваш источник, чтобы нормально работать для моего дела.Особенно я увлекаюсь ситуацией, когда мне нужно использовать рекурсию для работы по всем спискам, и если я обнаруживаю, что у двух списков есть хотя бы один подобный элемент, я могу объединить их вместе через функцию 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]. Вы видите мою точку зрения? Мне нужно как-то повторить так же и обратно. Такая ситуация для меня совершенно тупика. Удивление, если есть лучшее решение для моей главной цели, которое печатает все части отключенного графика на основе вставленных пользователем краев.

+1

привет. (а) в соответствии с рекомендациями SO вы действительно должны задать это как еще один вопрос, дав ссылку на этот контекст. (б) да, я вижу вашу точку зрения; то, что я предложил, будет работать именно таким образом; хотя я только дал вам качественный прогноз, так сказать, то, что я покажу, только покажет вам, что есть какая-то пара, которая трогает, но она не даст вам этих двух элементов - этого конкретного предиката, который вам нужно закодировать.Это вернет вас, предположительно, к двум касающимся элементам и к остальным, так что вы можете отложить оставшийся сегмент вместе с остальными. Поэтому, пожалуйста, удалите это A и спросите –

+0

Итак, пожалуйста, удалите этот ответ и задайте новый вопрос. Ваш новый код будет использовать 'touching' и' join', но вам все равно придется делать 'picking', так сказать. И причина, по которой я вам так дозволяю, заключается в том, что @ рефералы не работают в ответах, только в комментариях. Таким образом, я не получил ping и видел ваш комментарий только случайно. :) Вы действительно должны удалить этот вопрос, иначе он может закрыться модератором как «не ответ». –