Например, у меня есть 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.
Пролог объединяет два списка
Ответы (3)
Эта задача мне кажется не очень понятной, но давайте попробуем:
Мое первое наблюдение состоит в том, что все три списка имеют одинаковую длину. И что фактически у вас есть здесь поэлементное отображение, подобное этому:
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).
Я определил следующий предикат для решения этой задачи.
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 !, чтобы прекратить поиск решений.
merge([], [], []). не удается?
- person false; 30.05.2014
Попробуйте что-то вроде этого:
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.
. %
Другие стратегии работы со списками источников разной длины:
- потерпеть неудачу
- отбросить лишнее
nil правильно. Его представление называется по умолчанию.
- person false; 31.05.2014