在java中打破递归

2022-09-01 09:21:54

递归是一种“分而治之”的风格,它在变小时分裂(树数据结构),如果发现违规行为,我希望它完全中断,这意味着打破所有递归路径,并返回true。这可能吗?


答案 1

无论你做什么,你都必须展开堆栈。这留下了两个选项:

  1. 魔术返回值(如其中一个汤姆人所描述的)
  2. 抛出一个异常(如 thaggie 所提到的)

如果你希望事情死亡的情况很少见,这可能是抛出异常可能是一个可行的选择。在每个人都对此嗤之以鼻之前,请记住,编程最重要的规则之一是知道何时适合打破规则。

事实证明,我今天花了一些时间从谷歌代码中评估zxing库。它们实际上对许多控制结构使用异常抛出。当我看到它时,我的第一印象是恐怖。从字面上看,他们使用不同的参数调用了数万次方法,直到该方法没有引发异常。

这当然看起来像是一个性能问题,所以我做了一些调整,将事情改成使用魔术返回值。你知道吗?在调试器中运行时,代码速度提高了 40%。但是当我切换到非调试时,代码的速度不到1%。

在这种情况下,我仍然对使用异常进行流控制的决定并不疯狂(我的意思是,异常一被抛出)。但是,鉴于几乎不可估量的性能差异,我当然不值得花时间重新实现它。

如果触发迭代死亡的条件不是算法的基本部分,则使用异常可能会使代码更加干净。对我来说,我做出这个决定的要点是,如果需要解开整个递归,那么我会使用一个例外。如果只有部分递归需要解卷,请使用魔术返回值。


答案 2

您可以返回错误代码,或修改一些全局变量,以便每个递归实例都知道“杀死自己”。

类似的东西。

int foo(bar){
     int to_the_next;

      if (go_recursive){
            to_the_next = foo(whisky_bar);

            if (to_the_next ==DIE) return DIE;
      }

      if (something_unexpected_happened) return DIE;

      process;//may include some other recursive calls, etc etc
}

推荐