我如何 return 给定列表中的数字列表 mod 0 目标数字?
How can I return a list of numbers from a given list that mod 0 a target number?
在我的函数 modded(X,Y,Z) 中,根据给定的数字 Y 和给定的数字列表 Z 生成一个列表。我想要做的是为每个数字遍历列表 Z它的值,看看列表中的当前值是否会干净地除以 Y,(Y/Zz == 0)
。我对如何访问每个 Z 的值有点困惑,因为 Prolog 没有传统的迭代器。
预期的行为是将 (X,16,[2,3,4,5,7,8]) 修改为 return [2,4,8] 的列表。只允许完整的除数。
modded([],Y,Z):-
% X is the generated list, Y is the number, Z is a list of given numbers.
%Base case: Z is empty
Z =:= [],
X =:= Z.
modded([Zz|T],Y,[H|T]):-
%Recursive is Y > 1, Zz is an element of Z
0 is Y mod Zz,
Y =< Z - 1,
Zz is Z + 1,
% Want to add to a if Y mod Zz == 0
modded(T,Y,Zz).
modded([], _, []).
modded([Zz|T], Y, [Zz|Z]) :- % Case where Zz is a divisor of Y.
0 =:= Y mod Zz,
modded(T, Y, Z).
modded(T, Y, [Zz|Z]) :- % Case where Zz is not a divisor of Y.
0 =\= Y mod Zz,
modded(T, Y, Z).
然后
?- modded(X,16,[2,3,4,5,7,8]).
X = [2, 4, 8]
基本情况适用于输入和输出的空列表。
如果 Zz 是除数并添加到结果列表 [Zz|T] 中,则中间情况成立。
如果 Zz 不是除数且未添加到结果列表 T,则最后一种情况成立。
两种计算情况都递归剩余的 Z 列表以填充剩余的结果 T。
如果你不是被迫使用递归,你可以这样写:
modded(X, Y, Z) :-
findall(Zz, (member(Zz, Z), 0 =:= Y mod Zz), X).
“找到所有Z的成员和Y的约数的Zz,并将它们存储在X中”。
或
num_divisor(Y, Zz) :-
0 =:= Y mod Zz.
modded(X, Y, Z) :-
include(num_divisor(Y), Z, X).
您可能需要听到但可能不会关心的评论:
如果您使用的是 SWI Prolog,那么 https://swish.swi-prolog.org/ 是一个出色的工具,您可以在没有 edit/saving/reload 的情况下立即尝试一些代码。尝试将您的一些代码放入其中:
Z =:= []
Type error: `evaluable' expected, found `[]' (an empty_list)
那条线永远行不通。下一行也不是:
X =:= Z.
Arguments are not sufficiently instantiated
In:
[1] _1722=:=_1724
在 modded([Zz|T],Y,[H|T])
行中,通过在那些地方使用 T
,您是说两个列表的尾部必须相同。这些列表之一是输入,一个是过滤后的输出。那不行。
0 is Y mod Zz
行说 Zz 除 Y。modded
的参数不应该是(结果、数字、输入)吗?所以 modded([Zz|T],Y,[H|T])
不会是 H
分成 Y,而不是 Zz
还没有价值吗?
在 0 is Y mod Zz
行中它说 Zz 除以 Y。但是如果它确实有效并且输入到达 3
则该行将是错误的,因为 3 不能平均除以 16,所以整个程序会失败。如果数字不是除数,则无法处理该怎么做。
行 Y =< Z - 1
也不像其他语言那样工作,=<
不会计算 Z - 1。这几乎是幸运的,因为 Z 在代码中没有值。 (即使它有,你不是说它是输入列表吗? Y =< [2,3,4,5,7,8] - 1 会是什么?)
Zz is Z + 1
Z 在这里也没有值,但如果它有它就会失败,因为 Zz 在顶部与 modded([Zz
绑定并且它
modded(T,Y,Zz)
不是输入列表 modded
的最后一个参数,为什么它现在是除数?第一个参数是结果,现在是输入列表的尾部?
是的,你很困惑,你需要先熟悉基础知识,然后再尝试构建它们。
Recursing down lists 在 LearnPrologNow。
在我的函数 modded(X,Y,Z) 中,根据给定的数字 Y 和给定的数字列表 Z 生成一个列表。我想要做的是为每个数字遍历列表 Z它的值,看看列表中的当前值是否会干净地除以 Y,(Y/Zz == 0)
。我对如何访问每个 Z 的值有点困惑,因为 Prolog 没有传统的迭代器。
预期的行为是将 (X,16,[2,3,4,5,7,8]) 修改为 return [2,4,8] 的列表。只允许完整的除数。
modded([],Y,Z):-
% X is the generated list, Y is the number, Z is a list of given numbers.
%Base case: Z is empty
Z =:= [],
X =:= Z.
modded([Zz|T],Y,[H|T]):-
%Recursive is Y > 1, Zz is an element of Z
0 is Y mod Zz,
Y =< Z - 1,
Zz is Z + 1,
% Want to add to a if Y mod Zz == 0
modded(T,Y,Zz).
modded([], _, []).
modded([Zz|T], Y, [Zz|Z]) :- % Case where Zz is a divisor of Y.
0 =:= Y mod Zz,
modded(T, Y, Z).
modded(T, Y, [Zz|Z]) :- % Case where Zz is not a divisor of Y.
0 =\= Y mod Zz,
modded(T, Y, Z).
然后
?- modded(X,16,[2,3,4,5,7,8]).
X = [2, 4, 8]
基本情况适用于输入和输出的空列表。
如果 Zz 是除数并添加到结果列表 [Zz|T] 中,则中间情况成立。
如果 Zz 不是除数且未添加到结果列表 T,则最后一种情况成立。
两种计算情况都递归剩余的 Z 列表以填充剩余的结果 T。
如果你不是被迫使用递归,你可以这样写:
modded(X, Y, Z) :-
findall(Zz, (member(Zz, Z), 0 =:= Y mod Zz), X).
“找到所有Z的成员和Y的约数的Zz,并将它们存储在X中”。
或
num_divisor(Y, Zz) :-
0 =:= Y mod Zz.
modded(X, Y, Z) :-
include(num_divisor(Y), Z, X).
您可能需要听到但可能不会关心的评论:
如果您使用的是 SWI Prolog,那么 https://swish.swi-prolog.org/ 是一个出色的工具,您可以在没有 edit/saving/reload 的情况下立即尝试一些代码。尝试将您的一些代码放入其中:
Z =:= []
Type error: `evaluable' expected, found `[]' (an empty_list)
那条线永远行不通。下一行也不是:
X =:= Z.
Arguments are not sufficiently instantiated
In:
[1] _1722=:=_1724
在 modded([Zz|T],Y,[H|T])
行中,通过在那些地方使用 T
,您是说两个列表的尾部必须相同。这些列表之一是输入,一个是过滤后的输出。那不行。
0 is Y mod Zz
行说 Zz 除 Y。modded
的参数不应该是(结果、数字、输入)吗?所以 modded([Zz|T],Y,[H|T])
不会是 H
分成 Y,而不是 Zz
还没有价值吗?
在 0 is Y mod Zz
行中它说 Zz 除以 Y。但是如果它确实有效并且输入到达 3
则该行将是错误的,因为 3 不能平均除以 16,所以整个程序会失败。如果数字不是除数,则无法处理该怎么做。
行 Y =< Z - 1
也不像其他语言那样工作,=<
不会计算 Z - 1。这几乎是幸运的,因为 Z 在代码中没有值。 (即使它有,你不是说它是输入列表吗? Y =< [2,3,4,5,7,8] - 1 会是什么?)
Zz is Z + 1
Z 在这里也没有值,但如果它有它就会失败,因为 Zz 在顶部与 modded([Zz
绑定并且它
modded(T,Y,Zz)
不是输入列表 modded
的最后一个参数,为什么它现在是除数?第一个参数是结果,现在是输入列表的尾部?
是的,你很困惑,你需要先熟悉基础知识,然后再尝试构建它们。
Recursing down lists 在 LearnPrologNow。