Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 递归回溯仅适用于小输入。较大的输入会导致堆栈溢出_Java_Recursion_Backtracking - Fatal编程技术网

Java 递归回溯仅适用于小输入。较大的输入会导致堆栈溢出

Java 递归回溯仅适用于小输入。较大的输入会导致堆栈溢出,java,recursion,backtracking,Java,Recursion,Backtracking,我正在处理一个似乎需要某种回溯的问题。我有一个有效的递归方法,但是stackOverFlow会在输入较大时发生。这可以通过迭代实现来解决吗?我正在尝试实现一种方法,该方法采用两个目标值a和b。从a=1和b=1开始,需要多少个“加法”才能达到目标a和b值?加法可以使a=a+b或b=b+a,但不能同时使两者。 例如,如果目标a=2,目标b=1,则需要1“添加”。a=1&b=1,a=a+b=2 public static String answer(String M, String F) {

我正在处理一个似乎需要某种回溯的问题。我有一个有效的递归方法,但是stackOverFlow会在输入较大时发生。这可以通过迭代实现来解决吗?我正在尝试实现一种方法,该方法采用两个目标值a和b。从a=1和b=1开始,需要多少个“加法”才能达到目标a和b值?加法可以使a=a+b或b=b+a,但不能同时使两者。 例如,如果目标a=2,目标b=1,则需要1“添加”。a=1&b=1,a=a+b=2

public static String answer(String M, String F) { 
    return answerRecur(new BigInteger(M), new BigInteger(F), 0);
}   

public static String answerRecur(BigInteger M, BigInteger F, int its) {
    if(M.toString().equals("1") && F.toString().equals("1")) {
        return "" + its;
    }
    else if(M.compareTo(new BigInteger("0")) <=0 || F.compareTo(new BigInteger("0")) <=0) {
        return "impossible";
    }
    String addM = answerRecur(M.subtract(F), F, its +1);
    String addF = answerRecur(M, F.subtract(M), its +1);
    if(!addM.equals("impossible")) {
        return addM;
    }
    if(!addF.equals("impossible")) {
        return addF;
    }
    return "impossible";
}
公共静态字符串应答(字符串M,字符串F){
返回answerRecur(新的BigInteger(M),新的BigInteger(F),0);
}   
公共静态字符串应答器(BigInteger M、BigInteger F、int its){
如果(M.toString()等于(“1”)&F.toString()等于(“1”)){
返回“+”其名称;
}

否则,如果(M.compareTo(new BigInteger(“0”))递归回溯通过遍历所有候选步骤而起作用,则执行一个步骤,递归,撤消该步骤

这意味着,如果一个解决方案包含N个项,理想情况下递归深度不会超过N

所以:溢出是不可能的,可能尝试了太多,甚至无限重复

然而,在您的情况下,BigInteger可能足够大,并且当使用小步(1)时,将具有非常高的递归深度。并且每次调用都会创建足够多的递归。最好是int或long,而不是BigInteger

在每次通话中,您都有两名候选人:

  • M.减去(F)
  • F.减去(M)
如果对两者都进行评估,则在发现结果时可以停止

同时,(数学方面的)智慧也缺失了:最好是避免过多的步骤,找到尽可能直接的解决方案。一般来说,这可以通过对(2)个候选项进行排序来实现

如何得出一个聪明的解决方案?首先,数学必须可读,什么是BigInteger更小。手动尝试一些示例解决方案,并寻找一种聪明的方法来排序尝试

假设M和F为正,可以缩短递归:

if (M.compareTo(BigInteger.ZERO) <= 0 || F.compareTo(BigInteger.ZERO) <= 0) {
    return "impossible";
}
if (M.equals(BigInteger.ONE)) {
    return String.valueOf(F.intValue() - 1 + its);
}
if (F.equals(BigInteger.ONE)) {
    return String.valueOf(M.intValue() - 1 + its);
}
尽管有不止一个递归调用,但在这里考虑迭代解决方案实际上是可能的,但这不会增加质量

备注:

  • 按照java惯例,变量名应该使用
    f
    m
  • 真的需要BigInteger吗?它会导致代码有点笨拙

这是一个“是”还是“否”的问题?您必须提供更多详细信息……但如果方法被多次调用,递归固有的堆栈溢出错误。可能是的,如果您可以使用迭代而不是递归生成逻辑,则可能不会出现此错误。请添加递归所需的所有代码方法,以及对它的调用。欢迎使用SO。简短的答案是肯定的。要获得更长的答案,请选择a并查看。非常感谢!!!M和F的前提条件都是M
if (M.compareTo(F) > 0) {
    String addM = answerRecur(M.mod(F), F, its + M.divided(F).intValue());
}