我可以在prolog的列表中对数字进行平方吗?
列表可以包含数字,原子和列表。
例如:[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)
).
答案 0 :(得分:3)
我们定义了一个描述一个列表A与另一个列表之间关系的谓词,B:B应该具有与A相同的所有元素,除了A中的任何数字都应该在B中平方。
你出错的地方:
square([],X)
表示当A为空时,B就是任何东西(例如,甚至类似square([], 15)
的东西都是真的)。但这并没有捕捉到我们所追求的含义,因为第二个参数应该是一个与第一个参数数量相同的列表。也就是说,当第一个列表为空时,第二个列表应为空。a
的情况下(如示例所示),number(a)
将为false。由于谓词没有附加规则,除非第一个列表中的每个成员都是数字,否则它将是假的。<variable> is <expression>
的Prolog语句也是如此。你写的是 a = a * a ,但情况并非如此。*您所定义的内容大致是这样的:列表B是列表A的平方版本,如果A是空列表而B是任何OR,如果A的第一个元素是数字,那么number等于其自身的平方,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)
).