递归功能无法正常工作

时间:2014-12-17 02:12:23

标签: java arrays recursion

我有一个编写程序的任务,该程序将输入w,h和0到1之间的原始数组值输出,并输出"分子的数量"在表中。 W和h是表格的宽度和高度。分子是表的一部分,它与值1连接到向上或向下或向左或向右(没有对角线)。

示例输入:
     4 4
     1101
     1000
     1011
     1001

输出: 3

我写了一个程序,它生成一个带有预定义w和h的数组,然后用0到1的值随机填充它们,这样我就可以测试我的递归函数,但是我被卡住了。我的功能并不想转向左边" / j--而且可能是i--。有什么想法吗?

package firstSoup;

import java.util.Random;
import java.util.Scanner;

public class SoupMain {

static int width = 6;
static int height = 4;

static int[][] table;
static int moleculeCount = 0;

public static void main(String[] args) {

    Random random = new Random();       

    table = new int[height][width];

    //Fill the table with random numbers between 0 and 1 inclusive
    for(int i = 0; i < height; i++){
        for(int j = 0; j < width; j++){
            table[i][j] = random.nextInt(2);
        }
    }

    //Check the the table for a possible value of 1 and turn the whole "molecule" to value of 0
    //Increment moleculeCount
    for(int i = 0; i < height; i++){
        for(int j = 0; j < width; j++){
            if(table[i][j] == 1){
                turnOff(i, j);
                moleculeCount++;
            }
        }
    }
}

//Recursive function for turning only the values of 1 that are connected ("molecule") to 0
public static void turnOff(int i, int j){
    if(table[i][j] == 1){
        table[i][j] = 0;

        if(j < width-1){
        turnOff(i, j++);
        }

        if(j > 0){
        turnOff(i, j--);
        }

        if(i < height-1){
        turnOff(i++, j);
        }

        if(i > 0){
        turnOff(i--, j);
        }

    }else{
        return;
    }       
}
}

这是每次第一次turnOff呼叫的程序流程:
输入:
100100个
101110个
110011个
100011个

1
000100
001110
000011
000011
2
000000
00 1 000
000000
000000
3
000000
000000
000000
000000
输出= 3

什么时候看起来像这样:
输入:
100100个
101110个
110011个
100011个

1
000100
001110
000011
000011
2
000000
000000
000000
000000
输出= 2

1 个答案:

答案 0 :(得分:1)

您的问题是,在进行递归调用时,您正在使用后缀运算符来递增/递减索引值。在这种情况下,i+1i++会做很多不同的事情。

i++i--不仅评估为'one more than i''one less than i',还会更改 i的值在计划中继续前进。此外,它们仅在使用后计算递增/递减值

让我们来看看当你的董事会看起来像这样时会发生什么:

000100
001110
000011
000011

您的主循环将调用turnOff(0, 3),如下所示:

public static void turnOff(int i, int j) {
    // i=0, j=3
    if (table[i][j] == 1) {
        table[i][j] = 0;

        if (j < width - 1) {
            turnOff(i, j++);  // calls turnOff(0,3) and sets j=4
        }

        if (j > 0) {
            turnOff(i, j--); // calls turnOff(0,4) and sets j=3
        }

        //etc

这会搞砸你的边界检查并进行许多无序和冗余调用,这会破坏你的算法。您希望做的是在与当前单元格相邻的每个单元格上调用递归方法:

public static void turnOff(int i, int j) {
    // i=0, j=3
    if (table[i][j] == 1) {
        table[i][j] = 0;

        if (j < width - 1) {
            turnOff(i, j+1);  // calls turnOff(0,4)
        }

        if (j > 0) {
            turnOff(i, j-1);  // calls turnOff(0,2)
        }

        //etc

从长远来看,我不能强调学习使用调试器的重要性。你的大脑“看到”你认为你写的是什么,而不是你实际写的。在你对一个变量设置监视并看到它做出意想不到的事情之前,通常很难确定你的程序在哪里误入歧途。