递归+回溯。什么回报?

时间:2013-02-14 04:18:10

标签: string algorithm recursion backtracking

我遇到了一些这些问题,从来没有真正知道处理它的最佳方法。如果我正在编写递归函数并建立答案,但发现当前答案不起作用,我该返回什么。

如果答案应该是一个ArrayList,例如,我不能返回false来说它不起作用。 - 我应该返回一个像null或-1的sentinel值并在递归调用中检查它吗? - 或者该函数应该返回void并且只有在我确定答案时才添加到函数外部的变量 - 或者我应该存储一个保存值的额外参数,如果它不起作用就忽略它(我不知道如何在我当前的例子中这样做) - 或者我应该首先使用检查其是否有效的功能然后执行操作

我目前想要解决的问题类似于计算字符串中的所有排列。不同之处在于,在排列中具有两个连续字符的排列在字母表中不能是连续的,并且顺序相同。例如,不允许“bc”。 “cb”没关系。 不确定这是否是我的问题的一个很好的例子,但如果没有,我的问题仍然存在,因为我总是感到不舒服处理回溯递归。

2 个答案:

答案 0 :(得分:1)

是的,通常的方法是返回一个预定义的值(例如-1,或者某些常量,否则你无法从函数的正常操作中获得)。或者,您可以引发异常,然后在递归调用中捕获它。

答案 1 :(得分:0)

从你的问题来看,我认为你的行为是这样的:

struct my_object *rec_foo(int param /* ... */)
{
    my_object *tmp = NULL;
    int x;
    /*
     * Do something
     */

    /*
     * Here you don't know how to handle
     * the case where rec_foo() fails
     */
    tmp = rec_foo(x /* ... */);
    /*
     * Other work
     */
    return tmp;
}

一种常见的模式是使用返回指针来携带错误代码。这是在Linux内核中进行的,其中-1到-1000之间的所有数字都可以作为错误转换为指针。您可以定义自己的代码并检查返回的指针。

另一个是返回包含错误的枚举值,而函数更新参数指针指向的数据。因此,你的函数的原型将成为

enum rec_foo_error {
    REC_FOO_NO_ERROR,
    REC_FOO_ERROR_1,
    REF_FOO_ERROR_LAST /* Just to retrieve quickly
                      the number of available errors */
};
// You could simply use an int instead, but this is elegant
enum rec_foo_error rec_foo(struct my_object *obj, int x /*, ... */);