简体   繁体   English

(Java)递归重载有麻烦

[英](Java) Having trouble with recursive overloading

I'm studying basic Java and I there's a question on a programming assignment that I'm having a lot of trouble with concerning recursive overloading of sort of a search method. 我正在学习基本的Java,并且在编程任务上存在一个问题,我在与某种搜索方法的递归重载有关时遇到很多麻烦。 Here's what I'm being asked to do: 这是我被要求做的事情:

Write a method that accepts a two-dimensional int[][] array as the parameter and searches for legal "paths" through it, starting at [0][0] and ending at the end of the array. 编写一个方法,该方法接受一个二维int [] []数组作为参数,并通过它搜索合法的“路径”,该路径从[0] [0]开始并在该数组的末尾结束。 (For instance if the array is declared [5][5] then the end would be [4][4]). (例如,如果数组声明为[5] [5],则结尾将为[4] [4])。

In order for a path to be legal, "jumps" must be performed between the cells until the end of the array is reached. 为了使路径合法,必须在单元格之间执行“跳转”,直到到达数组的末尾。 If a path doesn't end at the end of the array, it isn't legal. 如果路径未在数组末尾结束,则不合法。 Here's an example: 这是一个例子:

EX

The logic here is that a "jump" can be performed either to the right by the 10s and down by the 1s place of the number in the cell or vice versa, and the goal of the method is to return the number of legal pathways that exist through the array. 此处的逻辑是,可以在单元格中的数字的10s右边向右或1s向下执行“跳转”,反之亦然,该方法的目标是返回合法路径的数量通过数组存在。

This wouldn't really be so much of a problem if it wasn't for the fact that the professor has several requirements for the assignment: 如果不是因为教授对作业有几个要求,那么这实际上不是什么大问题。

1) Absolutely no loops - the method must be carried out completely through recursion. 1)绝对没有循环-该方法必须通过递归完全执行。 2) No global or constant variables 3) No changing the contents of the array or duplicating it 4) No creating or using other methods - overloading is encouraged (and probably required at this point) but writing a new method to assist in the process is out of the question. 2)没有全局变量或常量变量3)不能更改数组的内容或对其进行复制4)不能创建或使用其他方法-鼓励重载(这时可能需要重载),但是编写一个新方法来协助该过程毫无疑问。

Here's what I have so far: 这是我到目前为止的内容:

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;
        }
    }
  }
}

I do apologize for the long question - I've been stuck on this thing for a week and haven't been able to figure it out. 对于这个长期存在的问题,我确实表示歉意-我已经在这个问题上停留了一个星期,还没有弄清楚。

The array in the photo should give a result of 3 possible paths, but every time I run the method I get 0. 照片中的数组应该给出3条可能路径的结果,但是每次我运行该方法时,都会得到0。

Any help at all would be greatly appreciated. 任何帮助将不胜感激。 Thank you :) 谢谢 :)

I fixed the code. 我修复了代码。 Essentially I'd been going about the problem all wrong: I was missing a case check. 本质上,我一直在解决所有错误的问题:我错过了一个案例检查。 What I mean is that there are four possible outcomes for each subsequent recursion of the method: 我的意思是,该方法的每次后续递归都有四个可能的结果:

  1. The end of the array has been reached and the returned value should be 1. 已到达数组的末尾,返回值应为1。
  2. A jump that goes down by the tens place and right by the ones place is legal but the reverse is not true. 跳下十个位置然后右移一个位置是合法的,但相反的说法是不正确的。
  3. A jump that goes down by the ones place and right by the tens place is legal but the reverse is not true. 一次下降一个跳位,一次下降几十个跳位是合法的,但反之则不成立。
  4. Both of the aforementioned jumps are legal. 前述的两个跳跃都是合法的。

All I had to do once I realized that was to write a series of cascading if statements, each of which return a different value for the recursive function. 我意识到要做的就是编写一系列级联的if语句,每个语句为递归函数返回不同的值。 What I didn't understand before is that a return statement could contain more than one recursive call, which enables me to run the method again for each case simultaneously in a "divide-and-conquer" sort of way. 我以前不了解的是,return语句可以包含多个递归调用,这使我能够以“分而治之”的方式同时针对每种情况再次运行该方法。

The resulting code is: 结果代码为:

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;
            }
        }
    }
}
}

When I ran the method countPaths(int[][] array) on the array in the picture I posted in the original question, the returned result was 3, which is the correct answer. 当我在原始问题中发布的图片中的数组上运行方法countPaths(int [] [] array)时,返回的结果为3,这是正确的答案。

Special thanks to Imchpers who helped me with this code two weeks ago. 特别感谢Imchpers在两周前为我提供了此代码。 I hope this answer helps others who are struggling with these kinds of recursive functions in any language. 我希望这个答案能为其他使用任何语言的递归函数苦苦挣扎的人提供帮助。

here is my updated list of conflicts now that I've had time to review the code. 这是我更新的冲突列表,因为我有时间检查代码。

Your first problem as I discussed below is here: 我在下面讨论的第一个问题在这里:

        //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;
        }

When your program goes from countPaths(mat) to countPaths(mat, r, c, paths), the initial location at this step is mat[1][2]. 当您的程序从countPaths(mat)转到countPaths(mat,r,c,路径)时,此步骤的初始位置为mat [1] [2]。 When you perform the second if condition after the first one returns paths = 1, this if condition fails to hold true (as it should) and it returns the else { return paths; 当您在第一个条件之后执行第二个if条件返回路径= 1时,此if条件无法正确满足(应有),并且返回else {return path; }. }。 Because the paths at this step still equals 0, this returns paths = 0 which overrides your previous work done in the previous recursive return. 由于此步骤中的路径仍等于0,因此返回的路径= 0,它将覆盖您先前在递归返回中完成的工作。

Once this program finishes this step, it will return to countPaths(mat) which has the return value from countPaths(mat, r, c, paths) of 0. Because this method received a valid return, it will exit at this point and won't continue on to the next if condition here: 该程序完成此步骤后,将返回到countPaths(mat),其countCounts(mat,r,c,path)的返回值为0。由于此方法收到了有效的返回值,因此它将在此时退出并赢得如果出现以下情况,请不要继续进行下一个操作:

        //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);
        }

These are your two main problem areas which will require a bit of work to fix the code to solve. 这是您的两个主要问题领域,需要一些工作来修复要解决的代码。 My first main suggestion is having ONE return in your countPaths(mat) function which will return countPaths(mat, ones, tens, 0) starting at the initial location instead of at mat[1][2]. 我的第一个主要建议是在countPaths(mat)函数中返回一个,该函数将从初始位置而不是mat [1] [2]处返回countPaths(mat,ones,tens,0)。 Let your recursive function deal with all the jumps; 让您的递归函数处理所有跳转; don't try to do initial handling in the first function. 不要尝试在第一个函数中进行初始处理。 Once you get that part refactored, I think everything else will fall into place and you can make progress in other small problem areas. 一旦您重构了该部分,我认为其他所有内容都将落实到位,您可以在其他小的问题领域中取得进展。 Please feel free to come back here & edit your question and/or add a comment if you run into problems afterwards. 如果您以后遇到问题,请随时返回此处并编辑您的问题和/或添加评论。

Good luck! 祝好运!

 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;

 }

i see this question on programming course 20441 Intro to CS. 我在《 CS编程入门》课程20441上看到了这个问题。 i guess they many similar Recursive Question in the world 我想他们在世界上有许多类似的递归问题

now days i finish project on "System Programming Laboratory 现在,我完成了“系统编程实验室”上的项目
(C Unix Writing Compiler for Assembler ..(without linker) ) (用于汇编器的C.Unix编写编译器..(不带链接器))

Liran Franco Telecomtodays@gmail.com Liran Franco Telecomtodays@gmail.com

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM