保持非尾递归的计数

时间:2017-02-07 05:39:50

标签: recursion count ml

我正在用函数式语言(ML)编写几个递归函数,其中有几个函数需要保持计数。我不允许使用尾递归或辅助函数。我该如何计算?

例如,如果一个问题要求我删除字符串的第n个元素,在删除该元素之前,如何知道递归函数被调用了n次?

1 个答案:

答案 0 :(得分:0)

您可以将计数作为参数传递。我不懂ML,但在C风格的语言中,它是这样做的:

void processTreeNode(Node* node, int count) {

    foreach(Node* child in node->children) {
        processTreeNode( child, count + 1 );
    }
}

第一个电话的值通常为01

Node* root = ...
processTreeNode( root, 1 );

请注意,上面的示例实际上计算深度而不是迭代计数。

如果要计算实际调用函数的次数,可以使用全局状态的值(一个坏主意)或通过引用传递的线程局部值:

void processTreeNode(Node* node, int* count) {

    (*count)++;

    foreach(Node* child in node->children) {
        processTreeNode( child, count );
    }
}

第一个调用负责创建值和引用:

Node* root = ...
int   count = 0;
processTreeNode( root, &count );

这可以推广到算法" context"传递给所有函数调用的对象 - 如果它通过引用传递,那么这可以避免不必要的值复制和堆栈空间分配,并且在没有其他线程可以访问它的情况下是线程安全的:

class MyAlgorithmContext {
    int foo;
    string bar;
}

Node* root = ...
MyAlgorithmContext context;
context.foo = 123;
processTreeNode( root, &context );