(Java)在递归重载方面遇到麻烦

时间:2015-06-12 04:10:55

标签: java arrays search recursion

我正在学习基础Java,而且我对编程任务有一个问题,我在处理某种搜索方法的递归重载方面遇到了很多麻烦。这就是我被要求做的事情:

编写一个接受二维int [] []数组作为参数的方法,并从中搜索合法的“路径”,从[0] [0]开始,到数组末尾结束。 (例如,如果声明了数组[5] [5],则结束将是[4] [4]。

为了使路径合法,必须在单元之间执行“跳转”,直到到达阵列的末尾。如果路径未在数组末尾结束,则不合法。这是一个例子:

EX

这里的逻辑是“跳跃”可以在10s向右执行,向下执行单元格中数字的1s位置,反之亦然,该方法的目标是返回通过阵列存在的合法途径。

如果不是因为教授对作业有几个要求,那么这不会是一个很大的问题:

1)绝对没有循环 - 该方法必须通过递归完全执行。 2)没有全局变量或常量变量 3)不改变数组的内容或重复它 4)不创建或使用其他方法 - 鼓励过载(此时可能需要重载),但是编写一种新方法来协助过程是不可能的。

这是我到目前为止所拥有的:

public class Question4 {
//step 1 - location: [0][0]
    public static int countPaths(int[][] mat) {
        int current = mat[0][0];
        //case 1: x < 10
        if(current < 10) {
            //check right
            if(current < mat.length-1) {
                return countPaths(mat, current, 0, 0);
            }
            //check left
            if(current < (mat[0].length-1)) {
                return countPaths(mat, 0, current, 0);
            }
        //case 2: x >= 10
        } else if(current >= 10) {
            int tens = (int)(Math.floor(current / 10));
            int ones = current % 10;

            //check down by 10s, right by 1s
                if(tens < mat.length-1 && ones < mat[0].length-1) {
                return countPaths(mat, tens, ones, 0);
            }

            //check right by 10s, down by 1s
            if(ones < mat.length-1 && tens < mat[0].length-1) {
                return countPaths(mat, ones, tens, 0);
            }
        }

        return 0;
    }

    //step 2 - two options: down by 10s, right by 1s / right by 10s, down by 1s
    public static int countPaths(int[][] mat, int r, int c, int paths) {
        //check if the end of the array has been reached
        if(r == mat.length-1 && c == mat[r].length-1) {
            return paths + 1;
        } else {
            int current = mat[r][c], tens = (int)Math.floor(current / 10), ones = current % 10;

            //check down by 10s, right by 1s
            if(r + tens < mat.length-1 && c + ones < mat[r].length-1) {
                return countPaths(mat, r + tens, c + ones, paths);
            }

            //check down by 1s, right by 10s
            if(r + ones < mat.length-1 && c + tens < mat[r].length-1) {
                return countPaths(mat, r + ones, c + tens, paths);
            } else {
                return paths;
        }
    }
  }
}

我为这个长期的问题道歉 - 我已经被困在这件事上一个星期而且无法弄明白。

照片中的数组应该给出3个可能路径的结果,但每次运行该方法时我都会得到0。

任何帮助都将非常感谢。谢谢:))

3 个答案:

答案 0 :(得分:1)

我修复了代码。基本上我一直在解决这个问题:我错过了一个案例检查。我的意思是该方法的每次后续递归有四种可能的结果:

  1. 已到达数组的末尾,返回的值应为1.
  2. 在一个地方向右下方跳跃的跳跃是合法的,但事实恰恰相反。
  3. 一个地方和一个地方向下的跳跃是合法的,但反之则不然。
  4. 上述两种跳跃都是合法的。
  5. 一旦我意识到要编写一系列级联if语句,我就不得不这样做,每个语句都为递归函数返回一个不同的值。之前我没有理解的是,return语句可以包含多个递归调用,这使我能够在&#34;分而治之中同时为每个案例再次运行该方法。某种方式。

    结果代码是:

    public class Paths {
    public static int countPaths(int[][] a) {
        //declare method variables
        int start = a[0][0], tens = start / 10, ones = start % 10;
        boolean downByTens, downByOnes;
    
        //set the case booleans
        if(tens <= a.length-1 && ones <= a[tens].length-1) {
            downByTens = true;
        } else {
            downByTens = false;
        }
    
        if(ones <= a.length-1 && tens <= a[ones].length-1) {
            downByOnes = true;
        } else {
            downByOnes = false;
        }
    
        //check the cases, return the overloaded method
        if(downByTens) {
            if(downByOnes) {
                return countPaths(a, tens, ones) + countPaths(a, ones, tens);
            } else {
                return countPaths(a, tens, ones);
            }
        } else {
            if(downByOnes) {
                return countPaths(a, ones, tens);
            } else {
                return 0;
            }
        }
    }
    
    private static int countPaths(int[][] a, int row, int col) {
        //declare method variables
        int current = a[row][col], tens = current / 10, ones = current % 10, end = a[a.length-1][a[0].length-1];
        boolean downByTens, downByOnes;
    
        //set the case booleans
        if(row + tens <= a.length-1 && col + ones <= a[row + tens].length-1) {
            downByTens = true;
        } else {
            downByTens = false;
        }
    
        if(row + ones <= a.length-1 && col + tens <= a[row + ones].length-1) {
            downByOnes = true;
        } else {
            downByOnes = false;
        }
    
        //check to see if the end of the array has been reached
        if(current == end) {
            return 1;
        } else {
            //check the cases
            if(downByTens) {
                if(downByOnes) {
                    return countPaths(a, row + tens, col + ones) + countPaths(a, row + ones, col + tens);
                } else {
                    return countPaths(a, row + tens, col + ones);
                }
            } else {
                if(downByOnes) {
                    return countPaths(a, row + ones, col + tens);
                } else {
                    return 0;
                }
            }
        }
    }
    }
    

    当我在原始问题中发布的图片中的数组上运行方法countPaths(int [] [] array)时,返回的结果是3,这是正确的答案。

    特别感谢两周前帮助我使用此代码的Imchpers。我希望这个答案可以帮助那些在任何语言中努力解决这些递归函数的人。

答案 1 :(得分:0)

这是我最新的冲突列表,因为我有时间查看代码。

我在下面讨论的第一个问题是:

        //check down by 10s, right by 1s
        if(r + tens < mat.length-1 && c + ones < mat[r].length-1) {
            return countPaths(mat, r + tens, c + ones, paths);
        }

        //check down by 1s, right by 10s
        if(r + ones < mat.length-1 && c + tens < mat[r].length-1) {
            return countPaths(mat, r + ones, c + tens, paths);
        } else {
            return paths;
        }

当你的程序从countPaths(mat)转到countPaths(mat,r,c,paths)时,这一步的初始位置是mat [1] [2]。当你在第一个返回paths = 1之后执行第二个if条件时,这个if条件不能保持为true(应该如此)并返回else {返回路径; }。由于此步骤中的路径仍等于0,因此返回paths = 0,这将覆盖先前在上一次递归返回中完成的工作。

一旦这个程序完成这一步,它将返回countPaths(mat),它具有来自countPaths(mat,r,c,paths)的返回值为0.因为这个方法收到了一个有效的返回,它将在此处退出指向并且不会继续下一个if条件:

        //check down by 10s, right by 1s
            if(tens < mat.length-1 && ones < mat[0].length-1) {
            return countPaths(mat, tens, ones, 0);
        }

        //check right by 10s, down by 1s (this if condition)
        if(ones < mat.length-1 && tens < mat[0].length-1) {
            return countPaths(mat, ones, tens, 0);
        }

这是您的两个主要问题领域,需要一些工作来修复要解决的代码。我的第一个主要建议是在countPaths(mat)函数中返回一个返回countPaths(mat,ones,tens,0),从初始位置开始而不是mat [1] [2]。让你的递归函数处理所有的跳转;不要尝试在第一个函数中进行初始处理。一旦你重构了那部分,我认为其他一切都将落实到位,你可以在其他小问题领域取得进展。请随时回到这里&amp;如果您以后遇到问题,请编辑您的问题和/或添加评论。

祝你好运!

答案 2 :(得分:0)

 public static int countP(int a[][],int x,int y,int count)
 {
     if(row==(a.length-1) &&(cell==a[0].length-1)) {count++;
         return 1; }


if(x<a.length  && y<a[0].length )
         {
              System.out.println("cell ["+x+"]["+y+"]="+a[x][y]);

             int tmp1=a[x][y]%10;
             int tmp2=a[x][y]/10;
          return (countP(a,x+tmp1,y+tmp2,count) +countP(a, x+tmp2, t+tmp2, count));
        }    
     return 0;

 }

我在编程课程20441 CS简介中看到了这个问题。   我猜他们在世界上有许多相似的递归问题

现在我在&#34;系统编程实验室完成了项目 (用于汇编程序的C Unix编译编译器..(没有链接器))

Liran Franco Telecomtodays@gmail.com