在c ++中累积tail递归函数

时间:2016-01-27 05:39:56

标签: c++ recursion

我正在为我的大学做作业。我需要创建递归函数。

我的list_t界面包含以下功能:

List Interface
The file recursive.h defines the type "list_t" and the following operations on lists:
// EFFECTS: returns true if list is empty, false otherwise
bool list_isEmpty​ (const list_t& list);
// EFFECTS: returns an empty list.
list_t list_make​ ();
// EFFECTS: given the list (list) make a new list consisting of
// the new element followed by the elements of the
// original list.
list_t list_make​ (int elt, const list_t& list);
// REQUIRES: list is not empty
// EFFECTS: returns the first element of list
int list_first​ (const list_t& list);
// REQUIRES: list is not empty
// EFFECTS: returns the list containing all but the first element of list
list_t list_rest​ (const list_t& list);
// MODIFIES: cout
// EFFECTS: prints list to cout.
void list_print​ (const list_t& list);

对于这个列表我需要创建下面的函数描述

/*
* REQUIRES: fn must be associative.
* EFFECTS: return identity if list is empty.
* Otherwise, return the tail recursive equivalent of
* fn(list_first(list), accumulate(list_rest(list), fn, identity).
* Be sure to make your code tail recursive!
*
* For example, if you have the following function:
*
* int add(int x, int y);
*
* Then the following invocation returns the sum of all elements:
*
* accumulate(list, add, 0);
*
* The "identity" argument is typically the value for which
* fn(X, identity) == X and fn(identity, X) == X for any X.
*/
int accumulate (list_t list, int (*fn)(int, int), int identity);

如果相关的

,我已经准备好了和和产品的功能

该功能还需要遵循以下规则

●每个过程都必须是尾递归的。为了获得全额信贷,您的日常工作必须提供 正确的结果并提供尾递归的实现。 ●在编写这些函数时,您可以仅使用递归和选择。您不得使用goto,for,while或do-while ●无静态或全局变量 ●如果定义任何辅助函数,请务必将它们声明为“静态”,否则它们不会 在程序文件外可见。有关尾递归的更多信息,请参阅附录 和辅助函数。

1 个答案:

答案 0 :(得分:0)

作为一种起点,让我们手动而不是sum来实施accumulate

不使用尾递归:

有两种情况;列表是空的还是不是。

如果列表为空,则返回0.
如果不是,请将列表的第一个元素添加到列表其余部分的总和中。

int sum(list_t list)
{
    return list_isEmpty(list) 
           ? 0 
           : list_first(list) + sum(list_rest(list));
}

这不是尾递归的,因为在递归调用返回后,我们对结果执行添加。

使用尾递归:

为了使这个尾递归,我们需要引入一个参数来累积部分结果,所以我们定义了一个辅助函数。
("如果你定义"在你的描述中实际上是你应该提示的。)

同样,有两种情况;列表是空的还是不是。

如果列表为空,则返回累加器 如果不是,则将列表的第一个元素添加到累加器,并将其传递给递归调用,该调用将列表的其余部分相加。

static int sum_helper(list_t list, int accumulator)
{
    return list_isEmpty(list) 
           ? accumulator 
           : sum_helper(list_rest(list), list_first(list) + accumulator);
}

这是尾递归的,因为在递归调用之后没有任何反应。

现在我们可以用sum

来定义sum_helper
int sum(list_t list)
{
    return sum_helper(list, 0);
}

实现尾递归accumulate遵循相同的模式 - 在累积结果的位置添加参数。

您还应该遵循建议"有关尾递归和帮助函数的更多信息,请参阅附录"并且您可以查找术语"左侧折叠"有关此特定功能的更多信息。