2017-09-30 91 views
2

我有这样的嵌套列表:跳过列表元素的列表

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评估表达式的顺序。任何任何将不胜感激。

回答

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

它预先考虑到每一个列表中的变量,并预置变量(可能一个子表)到输出。

此外,我们在这里有两个谓词,价格为1:如果我们想要将列表中的所有子列表的头部弹出,我们今后也可以使用remove_heads/2

相关问题