Prolog 可能删除列表中的元素
Prolog possible removal of elements in a list
我被要求尝试搜索所有可能的结果,从列表的任何单个元素中删除任何数字。
例如,如果我有一个列表 X = [1,2,3]
remove(X, Y)
我的结果将是:
Y = [2,3]
Y = [1,1,3]
Y = [1,3]
Y = [1,2,2]
Y = [1,2,1]
Y = [1,2]
为此,我已经编写了 2 个解决方案,但我真的不知道我的解决方案的缺点是什么。我的教授一直告诉我有更好的方法。
我的第一个方法:
test(S1, S2):-
length(S1, L),
M is L -1,
between(0, M, N),
remove(S1, S2, N).
remove([H|T], [H2|T2], Heap):-
(
Heap>0->
H2 = H,
remove(T, T2, Heap-1);
between(1, H, N),
H2 is H - N,
T2 = T
).
我的第二种方法:
remove1([H|T], [H|TY]):-
not(T=[]),
remove1(T, TY).
remove1([H|T], S2):-
between(1, H, X),
HY is H - X,
( HY = 0-> S2 = T; S2=[HY|T]).
这两种方法都给出了相同的结果,但我真的很想知道如何才能做得更好。有人介意给我一些建议吗?
你必须:
- select 列表中的一项(编号)
- 用小于 selected 项
的数字替换 selected 项
- 或者完全删除 selected 项目
例如:
remove([N|Tail], [NX|Tail]):-
succ(N1, N),
between(1, N1, NX).
remove([_|Tail], Tail).
remove([N|Tail], [N|NTail]):-
remove(Tail, NTail).
第一个子句 select 是列表中的第一个项目,并用小于该项目的数字替换该项目。
第二个子句从列表中删除该项目(如您的示例所示,当您将 N 减去 selected 项目 (N) 它不会出现在第二个列表中。
第三个子句应用递归,将头项保持原样并将该过程应用于剩余列表。
这是另一个使用 append/3
的解决方案。我认为 @gusbro 的回答更优雅 and/or 高效。但这是另一种选择:
reduce(L, R) :-
append(L1, [X|L2], L),
( X1 is X - 1, % some element varies 1 to X-1
between(1, X1, Y),
append(L1, [Y|L2], R)
; append(L1, L2, R) % or the element is just removed
).
我被要求尝试搜索所有可能的结果,从列表的任何单个元素中删除任何数字。
例如,如果我有一个列表 X = [1,2,3]
remove(X, Y)
我的结果将是:
Y = [2,3]
Y = [1,1,3]
Y = [1,3]
Y = [1,2,2]
Y = [1,2,1]
Y = [1,2]
为此,我已经编写了 2 个解决方案,但我真的不知道我的解决方案的缺点是什么。我的教授一直告诉我有更好的方法。
我的第一个方法:
test(S1, S2):-
length(S1, L),
M is L -1,
between(0, M, N),
remove(S1, S2, N).
remove([H|T], [H2|T2], Heap):-
(
Heap>0->
H2 = H,
remove(T, T2, Heap-1);
between(1, H, N),
H2 is H - N,
T2 = T
).
我的第二种方法:
remove1([H|T], [H|TY]):-
not(T=[]),
remove1(T, TY).
remove1([H|T], S2):-
between(1, H, X),
HY is H - X,
( HY = 0-> S2 = T; S2=[HY|T]).
这两种方法都给出了相同的结果,但我真的很想知道如何才能做得更好。有人介意给我一些建议吗?
你必须:
- select 列表中的一项(编号)
- 用小于 selected 项 的数字替换 selected 项
- 或者完全删除 selected 项目
例如:
remove([N|Tail], [NX|Tail]):-
succ(N1, N),
between(1, N1, NX).
remove([_|Tail], Tail).
remove([N|Tail], [N|NTail]):-
remove(Tail, NTail).
第一个子句 select 是列表中的第一个项目,并用小于该项目的数字替换该项目。
第二个子句从列表中删除该项目(如您的示例所示,当您将 N 减去 selected 项目 (N) 它不会出现在第二个列表中。
第三个子句应用递归,将头项保持原样并将该过程应用于剩余列表。
这是另一个使用 append/3
的解决方案。我认为 @gusbro 的回答更优雅 and/or 高效。但这是另一种选择:
reduce(L, R) :-
append(L1, [X|L2], L),
( X1 is X - 1, % some element varies 1 to X-1
between(1, X1, Y),
append(L1, [Y|L2], R)
; append(L1, L2, R) % or the element is just removed
).