我有这个嵌套列表:
list = [[1, 2, 3, 4],
[2, 7, 2, 1],
[3, 3, 7, 5],
[4, 4, 1, 7]]
我正试图跳过这个嵌套列表的第一个列表,以及每个列表的第一个元素。我希望它变成这样:
list = [[7, 2, 1],
[3, 7, 5],
[4, 1, 7]]
到目前为止,我有这个:
% skip first list in list of lists
skip_first_list([_|Tail], Tail).
% attemping to skip first element in each of the lists
skip_first_list([[_ | HeadTail] | Tail], X) :-
skip_first_list(Tail, R),
append(R, [HeadTail], X).
哪个不能产生正确的结果:
?- skip_first_list([[1, 2, 3, 4], [2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]], X).
X = [[2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]] ;
X = [[3, 3, 7, 5], [4, 4, 1, 7], [2, 3, 4]] ;
X = [[4, 4, 1, 7], [7, 2, 1], [2, 3, 4]] ;
X = [[3, 7, 5], [7, 2, 1], [2, 3, 4]] ;
false.
而我正在回答这个问题:
X = [[7, 2, 1], [3, 7, 5], [4, 1, 7]]
我的结果到目前为止似乎显示我正在以反向/错误的顺序追加,我该如何解决这个问题?我真的不明白Prolog评估表达式的顺序。任何任何人将不胜感激。
答案 0 :(得分:3)
规范是你提供一份清单列表:
所以我们最好把它分成两个谓词:
remove_heads/2
,删除所有子列表的头部;和remove_upper_left/2
删除第一个子列表,然后使用上面的谓词弹出子列表的头部。我们可以使用递归来执行remove_heads/2
:
remove_heads([],[]).
remove_heads([[_|H]|T],[H|T2]) :-
remove_heads(T,T2).
最后我们的remove_upper_left/2
忽略了列表的头部,并用尾巴调用remove_heads
:
remove_upper_left([_|T],T2) :-
remove_heads(T,T2).
或完整:
remove_heads([],[]).
remove_heads([[_|H]|T],[H|T2]) :-
remove_heads(T,T2).
remove_upper_left([_|T],T2) :-
remove_heads(T,T2).
然后产生:
?- remove_upper_left([[1, 2, 3, 4], [2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]],X).
X = [[7, 2, 1], [3, 7, 5], [4, 1, 7]].
也在相反的方向工作:
?- remove_upper_left(X, [[1, 2, 3, 4], [2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]]).
X = [_G1364, [_G1370, 1, 2, 3, 4], [_G1376, 2, 7, 2, 1], [_G1382, 3, 3, 7, 5], [_G1388, 4, 4, 1|...]].
所以这里它为每个列表添加一个变量,并将一个变量(可能是一个子列表)预先添加到输出中。
此外,我们这里有两个谓词,价格为一:如果我们想在列表列表中弹出所有子列表的头部,我们也可以在将来使用remove_heads/2
。