繁体   English   中英

序言:列表中的平方数

[英]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)也为真)。 但这并没有捕获我们所追求的含义,因为第二个参数应该是与第一个参数具有相同成员数的列表。 也就是说,当第一个列表为空时,第二个列表应为空。
  • 您的递归规则也会出现相同的问题,因为在每次迭代中,都会传递一个不确定的变量,并且关于第一个列表和第二个列表之间的关系永远不会说。
  • 当alist的第一个元素是数字时,此规则才会成功。 在第一个元素为a的情况下(例如您的示例), number(a)将为false。 由于该谓词没有其他规则,因此除非第一个列表的每个成员都是一个数字,否则它将完全为假。
  • Prolog中的变量在它们出现的整个上下文中必须始终具有相同的一致值。 它们的作用类似于算术公式中的变量。 公式a + b - b = a对于ab的任何值都是正确 ,但*仅当ab在整个方程式中均被分配一个一致的值时。 在Prolog语句中, <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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM