[英]Prolog: square numbers in a list
如何在序言中对列表中的数字求平方?
该列表可以包含数字,原子和列表。
例如: [a,b,2,3,4,[3],[c,d,9]]
,答案应为[a,b,4,9,16,[3],[c,d,9]]
。 正如我们在答案中看到的,它应该是列表中值的浅平方。
2-> 4
3-> 9
4-> 16
到目前为止我尝试过的
square([],X).
square([A|B],X):-number(A), A is A*A, square(B,X).
X将包含平方值。 基本情况是接收到空列表时。 我检查(A)头是否为数字,然后对数字求平方,然后将A更改为A *A。然后对其余部分B求平方函数。
请指出我做错了什么。
编辑:正确答案如下。 由一名浴学家。 请阅读他的评论以获取详细说明。
squared_members([], []).
squared_members([L|Ls], [SqrdL|SqrdLs]) :-
number(L),
SqrdL is L * L,
squared_members(Ls, SqrdLs).
squared_members([L|Ls], [L|SqrdLs]) :-
\+number(L),
squared_members(Ls, SqrdLs).
和
squared_members([], []).
squared_members([L|Ls], [M|Ms]) :-
( number(L)
-> M is L * L, squared_members(Ls, Ms)
; M = L, squared_members(Ls, Ms)
).
我们正在定义一个谓词,该谓词描述一个列表A和另一个列表B之间的关系:B应该具有与A相同的所有元素,只是A中的任何数字都应在B中平方。
您哪里出错了:
square([],X)
表示,当A为空时,则B为任意值(例如,即使是square([], 15)
也为真)。 但这并没有捕获我们所追求的含义,因为第二个参数应该是与第一个参数具有相同成员数的列表。 也就是说,当第一个列表为空时,第二个列表应为空。 a
的情况下(例如您的示例), number(a)
将为false。 由于该谓词没有其他规则,因此除非第一个列表的每个成员都是一个数字,否则它将完全为假。 <variable> is <expression>
形式也是如此。 您所写的内容表示a = a * a ,但事实并非如此。 *您的定义大致是这样的:如果A是一个空列表,并且B是任何东西,或者如果A的第一个元素是数字,并且该数字等于,则列表B是列表A的平方形式的平方,而B是A其余部分的平方。
这是一种可能的解决方案:
squared_members([], []).
squared_members([L|Ls], [SqrdL|SqrdLs]) :-
number(L),
SqrdL is L * L,
squared_members(Ls, SqrdLs).
squared_members([L|Ls], [L|SqrdLs]) :-
\+number(L),
squared_members(Ls, SqrdLs).
注意,通过使两个列表共享变量或包含与变量之间的关系链相关的元素,该定义能够在两个列表之间建立有意义的关系(即SqrdL由于为L * L而与L相关)。 这个定义比您的定义多了一个子句,这使它能够考虑不是数字的列表成员:将这些成员不变地添加到第二个列表中。
使用If-Then-Else表示法进行更清晰表达的替代定义如下:
squared_members([], []).
squared_members([L|Ls], [M|Ms]) :-
( number(L)
-> M is L * L, squared_members(Ls, Ms)
; M = L, squared_members(Ls, Ms)
).
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.