Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Пролог объединяет два списка

Автор вопроса: JohnDowОтветов: 3

Например, у меня есть A = [a,b,c,d] и B = [[q,w,e],[r,t],[y,u],[i,o]] и я хочу создать такие пары C = [[a,[q,w,e]],[b,[r,t]],[c,[y,u]],[d,[i,o]]]. Я могу создать список пар, но я не хочу объединять всех друг с другом. Есть ли простой способ сделать это? Я просто не могу правильно определить проблему для Google.

listnested-listsprolog

Ответы

Ответ 1 · рейтинг 5 · false

Эта задача мне кажется не очень понятной, но давайте попробуем:

Мое первое наблюдение состоит в том, что все три списка имеют одинаковую длину. И что фактически у вас есть здесь поэлементное отображение, подобное этому:

a_b_c(A,B,[A,B]).

Теперь используйте maplist/4:

?- As = [a,b,c,d], Bs = [[q,w,e],[r,t],[y,u],[i,o]], maplist(a_b_c, As, Bs, Cs).
As = [a,b,c,d],
Bs = [[q,w,e],[r,t],[y,u],[i,o]],
Cs = [[a,[q,w,e]],[b,[r,t]],[c,[y,u]],[d,[i,o]]].

Однако, осмелюсь сказать, я действительно рассматривал бы скорее пары! Я не вижу никаких достоинств в приведенном выше представлении.

key_value_pair(K,V,K-V).

?-  As = [a,b,c,d], Bs = [[q,w,e],[r,t],[y,u],[i,o]], maplist(a_b_c, As, Bs, Cs).
As = [a,b,c,d],
Bs = [[q,w,e],[r,t],[y,u],[i,o]],
Cs = [a-[q,w,e],b-[r,t],c-[y,u],d-[i,o]].

maplist/4 - это общий предопределенный или библиотечный предикат. см. также этот пост. Если у вас его нет:

maplist(_C_3, [], [], []).
maplist(Cont_3, [A|As], [B|Bs], [C|Cs]) :-
   call(Cont_3, A, B, C),
   maplist(Cont_3, As, Bs, Cs).

Ответ 2 · рейтинг 2 · rareyesdev

Я определил следующий предикат для решения этой задачи.

merge([X], [Y], [[X,Y]]).
merge([X|L1], [Y|L2], [[X,Y]|L3]):-merge(L1, L2, L3).

Первая строка - это факт. Результатом объединения двух списков с одним элементом в каждом является список, содержащий только один элемент, то есть список с двумя элементами X и Y.

Вторая строка гласит, что: результатом слияния двух списков, содержащих не менее двух элементов, является список, в котором первый элемент равен списку из двух элементов (первый элемент каждого списка), а остаток является результатом слияния остатка первые два списка.

ИЗМЕНИТЬ:

Если вы хотите обработать случай пустых списков, вы можете использовать это определение:

merge([X], [Y], [[X,Y]]):-!.
merge([], [], []).
merge([X|L1], [Y|L2], [[X,Y]|L3]):-merge(L1, L2, L3).

Это немного сложнее, поскольку в нем используется предикат cut !, чтобы прекратить поиск решений.

Ответ 3 · Nicholas Carey

Попробуйте что-то вроде этого:

zip( []     , [Y|Ys  , [ nil:Y | Zs ] ) :- % for lists of unequal length,
  zip( [] , Ys , Zs ) .                    %   create unmatched pairs and recurse down
zip( [X|Xs] , []     , [ X:nil | Zs ] ) :- % for lists of unqual lengths,
  zip( Xs , [] , Zs ) .                    %   create unmatched paris and recurs down
zip( [X|Xs] , [Y|Ys] , [ X:Y   | Zs ] ) :- % otherwise
  zip( Xs , Ys , Zs )                      % - pair up and recurse down.
  .                                        %

Другие стратегии работы со списками источников разной длины:

  • потерпеть неудачу
  • отбросить лишнее

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы