[英]Prolog: square numbers in a list
Ho do I square numbers in a list in prolog? 如何在序言中对列表中的数字求平方?
The list can contain numbers, atoms and lists. 该列表可以包含数字,原子和列表。
for example: [a,b,2,3,4,[3],[c,d,9]]
and the answer should be [a,b,4,9,16,[3],[c,d,9]]
. 例如:
[a,b,2,3,4,[3],[c,d,9]]
,答案应为[a,b,4,9,16,[3],[c,d,9]]
。 As we see in the answer it should be a shallow squaring of the values in the list. 正如我们在答案中看到的,它应该是列表中值的浅平方。
2->4 2-> 4
3->9 3-> 9
4->16 4-> 16
What I have tried so far, 到目前为止我尝试过的
square([],X).
square([A|B],X):-number(A), A is A*A, square(B,X).
X will contain squared values. X将包含平方值。 Base case is when empty list is received.
基本情况是接收到空列表时。 I check if head (A) is a number then I go ahead square the number and change A to A * A. Then go ahead and call the square function for remaining part B.
我检查(A)头是否为数字,然后对数字求平方,然后将A更改为A *A。然后对其余部分B求平方函数。
Please suggest where I am doing wrong. 请指出我做错了什么。
EDIT: Correct answer as follows. 编辑:正确答案如下。 By aBathologist.
由一名浴学家。 Please read his comment for detailed explanation.
请阅读他的评论以获取详细说明。
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).
And 和
squared_members([], []).
squared_members([L|Ls], [M|Ms]) :-
( number(L)
-> M is L * L, squared_members(Ls, Ms)
; M = L, squared_members(Ls, Ms)
).
We're defining a predicate which describes the relationship between one list, A, and another list, B: B should have all the same elements as A, except that any number in A should be squared in B. 我们正在定义一个谓词,该谓词描述一个列表A和另一个列表B之间的关系:B应该具有与A相同的所有元素,只是A中的任何数字都应在B中平方。
Where you've gone wrong: 您哪里出错了:
square([],X)
, says that when A is empty, then B is anything (so, for instance, even something like square([], 15)
is true). square([],X)
表示,当A为空时,则B为任意值(例如,即使是square([], 15)
也为真)。 But this doesn't capture the meaning we're after, since the second argument should be a list with the same number of members as the first. a
(like in your example), number(a)
will be false. a
的情况下(例如您的示例), number(a)
将为false。 Since there are no additional rules for the predicate, it will simply be false unless every member of the first list is a number. <variable> is <expression>
. <variable> is <expression>
形式也是如此。 What you've written says a = a * a which cannot be the case. *What you're definition says is, roughly, this: The list B is a squared version of the list A if A is an empty list and B is anything OR if the first element of A is a number, and that number is equal to itself squared, and B is a squared version of the rest of A. *您的定义大致是这样的:如果A是一个空列表,并且B是任何东西,或者如果A的第一个元素是数字,并且该数字等于,则列表B是列表A的平方形式的平方,而B是A其余部分的平方。
Here's one possible solution: 这是一种可能的解决方案:
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).
Notice that this definition is able to establish a meaningful relationship between the two lists by having them either share variables, or contain elements related by a chain of relations between variables (ie, SqrdL is related to L by virtue of being L * L). 注意,通过使两个列表共享变量或包含与变量之间的关系链相关的元素,该定义能够在两个列表之间建立有意义的关系(即SqrdL由于为L * L而与L相关)。 This definition has one more clause then yours, which enables it to take account of the members of a list which are not numbers: those are added to the second list unaltered.
这个定义比您的定义多了一个子句,这使它能够考虑不是数字的列表成员:将这些成员不变地添加到第二个列表中。
An alternative definition, using If-Then-Else notation for cleaner expression, would be the following: 使用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.