我正在尝试删除列表列表中每个列表的第一个元素。 例如,要列出[[1,2],[3,4]],我应该返回[[2],[4]]。 在大多数情况下,以下代码可以正常工作:
remove_firstElem([],[]).
remove_firstElem([[_H|T]|Ls],[T|L]) :-
remove_firstElem(Ls,L).
但对于像[[1],[2]]这样的列表,我希望它返回[]而不是[[],[]]。
到目前为止,我尝试的是:
remove_firstElem([_H|Ls],L) :-
length(_H,1),
remove_firstElem(Ls,L).
但它返回[ ],[[ ]],[[ ]],[[ ],[ ]]
,我真的不知道它有什么问题。
任何人都可以帮我解决吗?谢谢你的帮助!
答案 0 :(得分:1)
如果我理解正确,你想要弹出列表的头部,但是如果列表只包含一个元素(或者根本没有),则应该删除该列表。
我们可以检查子列表是否包含至少两个带有模式的元素:
pop_lists([[_,H2|T]|TA],[[H2|T]|TB]) :-
pop_lists(TA,TB).
所以我们在第一个列表中有一个模式[_,H2|T]
。 _
与第一个元素绑定,H2
与第二个元素绑定,其余元素与尾部绑定。
无法与该模式统一的列表是空列表或包含一个元素的列表。所以在这种情况下我们完全忽略它们:
pop_lists([[]|TA],TB) :-
pop_lists(TA,TB).
pop_lists([[_]|TA],TB) :-
pop_lists(TA,TB).
如果我们到达列表的末尾,当然我们也将过滤器与空列表统一起来:
pop_list([],[]).
我们最好把这个子句放在第一行,使我们的谓词更加多向。总而言之,我们有以下解决方案:
pop_list([],[]).
pop_list([[_,H2|T]|TA],[[H2|T]|TB]) :-
pop_list(TA,TB).
pop_list([[]|TA],TB) :-
pop_list(TA,TB).
pop_list([[_]|TA],TB) :-
pop_list(TA,TB).
我们可以进一步对语句进行重新排序,以使回溯量减少:
pop_list([],[]).
pop_list([[]|TA],TB) :-
pop_list(TA,TB).
pop_list([[_]|TA],TB) :-
pop_list(TA,TB).
pop_list([[_,H2|T]|TA],[[H2|T]|TB]) :-
pop_list(TA,TB).
答案 1 :(得分:0)
更简单的方法:
list_tail([_|Es], Es).
maplist(list_tail, Input, Output).