我想删除Prolog中列表的最后n个元素,并将其放在另一个列表中,如L2。如果我知道要删除的元素的确切数量说3,这里是代码。但我坚持变量n案例。顺便说一下,如果列表的长度小于n,我想返回一个空字符串。谢谢。
without_last_three([], []).
without_last_three([_], []).
without_last_three([_,_], []).
without_last_three([_,_,_], []).
without_last_three([Head|Tail], [Head|NTail]):-
without_last_three(Tail, NTail).
答案 0 :(得分:5)
without_last_n(Old, N, New) :-
length(Tail, N),
append(New, Tail, Old).
试运行:
?- without_last_n([a, b, c, d, e, f], 4, New).
New = [a, b]
?- without_last_n([a, b, c, d, e, f], 777, New).
false.
?- without_last_n([a, b, c, d, e, f], 0, New).
New = [a, b, c, d, e, f]
更新。当N大于列表长度时,要成功[]
,可以添加第二个子句:
without_last_n(Old, N, []) :-
length(Old, L),
N > L.
答案 1 :(得分:0)
以下是一般情况:
without_last_n(L, N, []) :-
nonvar(L), nonvar(N),
length(L, M),
N > M.
without_last_n(L, N, R) :-
without_last_n_(L, N, R).
without_last_n_(L, N, []) :-
length(L, N).
without_last_n_([H|T], N, [H|T1]) :-
without_last_n_(T, N, T1).
这满足给定的要求,并且适用于各种变量实例化方案。如果without_last_n(L, N, []).
大于N
的长度,L
必须成功的要求使解决方案复杂化的原因。如果这不是一个要求,那么更简单的without_last_n_/3
就足以解决问题。
...测试
| ?- without_last_n([1,2,3,4], 3, R).
R = [1] ? ;
no
| ?- without_last_n([1,2,3,4], N, R).
N = 4
R = [] ? ;
N = 3
R = [1] ? ;
N = 2
R = [1,2] ? ;
N = 1
R = [1,2,3] ? ;
N = 0
R = [1,2,3,4]
(1 ms) yes
| ?- without_last_n([1,2,3,4], N, [1,2]).
N = 2 ? ;
no
| ?- without_last_n(L, 3, [1,2]).
L = [1,2,_,_,_] ? ;
no
| ?- without_last_n(L, 2, R).
L = [_,_]
R = [] ? ;
L = [A,_,_]
R = [A] ? ;
L = [A,B,_,_]
R = [A,B] ? ;
L = [A,B,C,_,_]
R = [A,B,C] ?
...
| ?- without_last_n(L, N, [1,2]).
L = [1,2]
N = 0 ? ;
L = [1,2,_]
N = 1 ? ;
L = [1,2,_,_]
N = 2 ? ;
...
| ?- without_last_n(L, N, R).
L = []
N = 0
R = [] ? ;
L = [_]
N = 1
R = [] ? ;
L = [_,_]
N = 2
R = [] ? ;
L = [_,_,_]
N = 3
R = [] ? ;
...
| ?-
这里可能存在的一个缺陷是,without_last_n([1,2,3,4], N, R).
可能会生成N = 5, R = []
,N = 6, R = []
等的解决方案 ad infinitum ,但事实并非如此。留给读者练习。 :)