【问题标题】:Recursion + backtracking. What to return?递归+回溯。要返回什么?
【发布时间】:2013-01-29 20:03:56
【问题描述】:

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

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

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

【问题讨论】:

    标签: string algorithm recursion backtracking


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      根据您的问题,我假设您有这样的行为:

      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 /*, ... */);
      

      【讨论】:

        猜你喜欢
        • 2021-12-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-07
        • 1970-01-01
        相关资源
        最近更新 更多