列表

时间:2015-05-26 04:45:00

标签: list recursion prolog

我很难理解prolog中的递归。我可以阅读示例,有时可以理解,但我实际上很难实现它们。例如,有人可以编码我如何找到列表中所有元素的总和,然后通过它吗?以及如何处理这样的问题的提示?谢谢!

2 个答案:

答案 0 :(得分:0)

一般的“好”解释是不可能的,因为一个好的解释需要链接到该人的先前的知识。举例来说,我要假设你能够通过归纳进行“证明”。

步骤1:让我们从最初的事实开始,“具有单个元素的集合的总和是元素本身”。在prolog:

sum([A],A).

步骤2:如果集合Q的和是SQ,则添加一个元素H的该集合的总和是H + SQ。在prolog:

sum([H|Q],R) :- sum(Q,SQ), R is H+SQ.

这就是全部,你解决了问题。但...

一般来说,我们尝试从最基本的集合开始,即空集,所以替换现在成为的“步骤1”:空集的元素之和为0:

sum([],0).

最后,如果规则是尾递归的(如果执行环境不能自己优化),则prolog更有效率。这意味着一点改变:

sum([],R,R).
sum([H|Q],SQ,R) :- T is SQ+H, sum(Q,T,R).

这些规则可以理解为:假设(断言)Q的总和是SQ。在这种情况下,集合Q加元素H的和是SQ + H.第一个意味着,当待处理集中没有更多元素时,结果直接是累计和。

答案 1 :(得分:0)

递归思考可能很难。关于如何递归思考的良好资源的链接,See my answer问题“Prolog programming - path way to a solution”。

例如,大多数递归问题可以分解为几个(1或2)特殊情况,然后是一般情况。在你的情况下 - 计算一个数字列表的总和 - 人们可能会看到它有1或两个特殊情况。首先,你必须做出决定:空列表的总和是多少?有人可能会争辩说空列表的总和为零,或者空列表没有总和。要么是有争议的,要么是完全有效的观点。

在任何一种情况下,特殊情况都是

  • []。空列表。空列表的总和为0或没有(在这种情况下,您的谓词应该失败。)

  • [100]。长度列表一。长度为1的列表的总和显然是第一个和唯一条目的值。

更一般的情况:

  • [100,101,102]。可以通过获取列表中第一项的值并计算余数的总和来计算长度大于1的列表的总和。注意

    • 解决方案是根据自身和
    • 定义的
    • 问题变得更小(通过从列表中删除第一项)。

    最终,问题将退化为特殊情况之一,对吗?

考虑到所有这些,让我们假设我们已经确定空列表的总和为0.这意味着我们的第二个特例(单个元素列表)消失了,给我们留下了一个可以解决的问题描述为

  • 空列表的总和为0.
  • 非空列表的总和由...计算
    • 从列表中删除第一项
    • 计算剩余项目的总和,
    • 将第1项的值添加到余数之和。

由于prolog是一种声明性语言,我们的解决方案将与解决方案的描述完全相同:

sum_of_list( []     , 0 ) .
sum_of_list( [N|Ns] , S ) :-
  sum_of_list(Ns,T) ,
  S is T+N
  .

c