Prolog 从列表中删除与索引具有相同值的元素
Prolog remove elements which have the same value as the index from the list
我的任务是从列表中删除与索引具有相同值的所有元素。我有这个代码,但它不起作用。
remove(_, [], []).
remove(position, [H | T1], [H | T2]) :-
H =:= position,
next_position = position + 1,
remove(next_position, T1, T2).
remove(position, [H | T1], T2) :-
H =\= position,
next_position = position + 1,
remove(next_position, T1, T2).
:-remove(1,[1, 2, 2, 3, 4, 5, 6, 7, 8],Res),
write(Res).
主要错误在句法上。还必须刷条件。现在它改变了,程序可以工作了。
解决方案:
remove(_, [], []).
remove(Position, [H | T1], [H | T2]) :-
H =\= Position,
NextPosition is Position + 1,
remove(NextPosition, T1, T2).
remove(Position, [H | T1], T2) :-
H =:= Position,
NextPosition is Position + 1,
remove(NextPosition, T1, T2).
:-remove(1,[1, 2, 2, 3, 4, 5, 6, 7, 8],Res),
write(Res).
除了 Gusbro 已经指出的修改之外,您还需要反转用于输入列表中 include/exclude 个元素的条件:
remove(_, [], []).
remove(Position, [H|T1], [H|T2]) :-
H =\= Position, % include element if it is different from its index
Next_position is Position + 1,
remove(Next_position, T1, T2).
remove(Position, [H|T1], T2) :-
H =:= Position, % exclude element if it is equal to its index
Next_position is Position + 1,
remove(Next_position, T1, T2).
示例:
% index 1 2 3 4
?- remove(1, [1,2,2,4], Res).
Res = [2] ;
false.
% index 0 1 2 3
?- remove(0, [1,2,2,4], Res).
Res = [1, 2, 4] ;
false.
% index 1 2 3 4 5 6 7 8 9
?- remove(1, [1,2,2,3,4,5,6,7,8], Res).
Res = [2, 3, 4, 5, 6, 7, 8] ;
false.
避免虚假选择点:
- 使用 wrapper 谓词以原始所需的顺序维护参数。
- 在 helper 谓词中,更改前两个参数的顺序,以利用 Prolog 的第一个参数索引。
- 使用
->
来避免评估确定性条件及其否定的需要。
因此,该谓词的改进版本如下:
improved_remove(Start, List, NewList) :-
remove_loop(List, Start, NewList).
remove_loop([], _, []).
remove_loop([H|T1], Position, L) :-
( H =\= Position
-> L = [H|T2]
; L = T2 ),
Next_position is Position + 1,
remove_loop(T1, Next_position, T2).
示例:
?- improved_remove(1, [1,2,2,4], Res).
Res = [2].
?- improved_remove(0, [1,2,2,4], Res).
Res = [1, 2, 4].
?- improved_remove(1, [1,2,2,3,4,5,6,7,8], Res).
Res = [2, 3, 4, 5, 6, 7, 8].
我的任务是从列表中删除与索引具有相同值的所有元素。我有这个代码,但它不起作用。
remove(_, [], []).
remove(position, [H | T1], [H | T2]) :-
H =:= position,
next_position = position + 1,
remove(next_position, T1, T2).
remove(position, [H | T1], T2) :-
H =\= position,
next_position = position + 1,
remove(next_position, T1, T2).
:-remove(1,[1, 2, 2, 3, 4, 5, 6, 7, 8],Res),
write(Res).
主要错误在句法上。还必须刷条件。现在它改变了,程序可以工作了。
解决方案:
remove(_, [], []).
remove(Position, [H | T1], [H | T2]) :-
H =\= Position,
NextPosition is Position + 1,
remove(NextPosition, T1, T2).
remove(Position, [H | T1], T2) :-
H =:= Position,
NextPosition is Position + 1,
remove(NextPosition, T1, T2).
:-remove(1,[1, 2, 2, 3, 4, 5, 6, 7, 8],Res),
write(Res).
除了 Gusbro 已经指出的修改之外,您还需要反转用于输入列表中 include/exclude 个元素的条件:
remove(_, [], []).
remove(Position, [H|T1], [H|T2]) :-
H =\= Position, % include element if it is different from its index
Next_position is Position + 1,
remove(Next_position, T1, T2).
remove(Position, [H|T1], T2) :-
H =:= Position, % exclude element if it is equal to its index
Next_position is Position + 1,
remove(Next_position, T1, T2).
示例:
% index 1 2 3 4
?- remove(1, [1,2,2,4], Res).
Res = [2] ;
false.
% index 0 1 2 3
?- remove(0, [1,2,2,4], Res).
Res = [1, 2, 4] ;
false.
% index 1 2 3 4 5 6 7 8 9
?- remove(1, [1,2,2,3,4,5,6,7,8], Res).
Res = [2, 3, 4, 5, 6, 7, 8] ;
false.
避免虚假选择点:
- 使用 wrapper 谓词以原始所需的顺序维护参数。
- 在 helper 谓词中,更改前两个参数的顺序,以利用 Prolog 的第一个参数索引。
- 使用
->
来避免评估确定性条件及其否定的需要。
因此,该谓词的改进版本如下:
improved_remove(Start, List, NewList) :-
remove_loop(List, Start, NewList).
remove_loop([], _, []).
remove_loop([H|T1], Position, L) :-
( H =\= Position
-> L = [H|T2]
; L = T2 ),
Next_position is Position + 1,
remove_loop(T1, Next_position, T2).
示例:
?- improved_remove(1, [1,2,2,4], Res).
Res = [2].
?- improved_remove(0, [1,2,2,4], Res).
Res = [1, 2, 4].
?- improved_remove(1, [1,2,2,3,4,5,6,7,8], Res).
Res = [2, 3, 4, 5, 6, 7, 8].