我为我的作业编写了Prolog代码,以删除给定列表的第n个元素。
我创建了一个名为remove/3
的谓词,它从列表中删除了一个元素,另一个名为drop2/4
的谓词仅通过可被整除的数字调用remove/3
谓词ñ
但是有一个小的逻辑错误,因为它只从列表中删除了1个元素,它是可被N整除的最后一个元素。我想这是因为当我用列表L调用remove/3
谓词时X它将所有元素添加到X然后删除元素编号N,但是,L保持不变,所以当我再次用另一个N调用remove/3
时,它不会继续上一次编辑,所以之前的编辑已删除的元素已恢复,因此只删除了最后一个元素。
查询示例:
drop([a,b,c,d,e,f,g,h,i,k], 3, X).
结果应为:X = [a,b,d,e,g,h,k]
drop(L, N, X):-
drop2(L, N, X, N).
drop2(_, _, _, 1).
drop2(L, N, X, C):-
N mod C =:= 0,
remove(L, N, X),
Z is C-1,
drop2(L, N, X, Z).
drop2(L, N, X, C):-
Z is C-1,
drop2(L, N, X, Z).
remove([_|T], 1, T).
remove([H|T1], N, [H|T2]):-
N > 1,
Z is N - 1,
remove(T1, Z, T2).
答案 0 :(得分:2)
这对我来说似乎很复杂。你可以说
drop(Xs,N,Rs) :-
integer(N) ,
N > 0 ,
drop(Xs,1,N,Rs)
.
你的助手谓词drop/4
是
drop( [] , _ , _ , [] ) .
drop( [X|Xs] , P , N , Rs ) :-
( 0 =:= P mod N -> R1 = Rs ; [X|R1] = Rs ) ,
P1 is P+1 ,
drop(Xs,P1,N,R1)
.
或等效的
drop( [] , _ , _ , [] ) .
drop( [X|Xs] , P , N , [X|Rs] ) :- 0 =\= P mod N , P1 is P+1 , drop(Xs,P1,N,Rs) .
drop( [_|Xs] , P , N , Rs ) :- 0 =:= P mod N , P1 is P+1 , drop(Xs,P1,N,Rs) .
甚至
drop( [] , _ , _ , [] ) .
drop( [_|Xs] , P , P , Rs ) :- P1 is 1 , drop(Xs,P1,N,Rs) .
drop( [X|Xs] , P , N , [X|Rs] ) :- P < N , P1 is P+1 , drop(Xs,P1,N,Rs) .
答案 1 :(得分:2)
无需编写递归代码......只需使用append/3
,length/2
和same_length/2
!
list_nth1_dropped(As,N1,Bs) :-
same_length(As,[_|Bs]),
append(Prefix,[_|Suffix],As),
length([_|Prefix],N1),
append(Prefix,Suffix,Bs).
以下是OP给出的查询:
?- Xs = [a,b,c,d,e,f,g,h,i,k], list_nth1_dropped(Xs,3,Ys). Xs = [a,b,c,d,e,f,g,h,i,k], Ys = [a,b, d,e,f,g,h,i,k] ; false.
更一般的查询怎么样?
?- list_nth1_dropped([a,b,c,d,e,f],N,Xs).
N = 1, Xs = [ b,c,d,e,f]
; N = 2, Xs = [a, c,d,e,f]
; N = 3, Xs = [a,b, d,e,f]
; N = 4, Xs = [a,b,c, e,f]
; N = 5, Xs = [a,b,c,d, f]
; N = 6, Xs = [a,b,c,d,e ]
; false.