1

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

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

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

4

2 回答 2

1

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

于 2013-02-14T04:20:31.143 回答
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 /*, ... */);
于 2013-02-14T10:21:20.893 回答