简体   繁体   中英

Recursive 2D 5x5 counting 'a' function in java

I have to write a method that returns the count of 'a' chars in the matrix but I have to do it with using recursion and it must be O(n.log(n)).

This is the my non-recursive code:

public static int acount(char[][] mat) {
    int result = 0;

    int i = 0;
    int j = 0;

    while (i <= 4) {
        if (mat[i][j] == 'a') {
            result++;
            j++;
        }
        if (mat[i][j] == 'b') {
            i++;
            j = 0;
        }
    }
    return result;
}

This is what i have tried but there was an error: "Exception in thread "main" java.lang.StackOverflowError":

public static int acount(char[][] mat) {
    int result = 0;

    int i = 0;
    int j = 0;

    while (mat[i][j] == 'a') {
        
        result++;
        j++;
        
    }

    if (i < 5) {
        
        i++;
        j = 0;

    } else {
        
        return result;
        
    }
    
    return acount(mat);
    
}

This is the main code:

public static void main(String[] args) {
    
    int n = 5;
    Random rand = new Random();
    char[][] input = new char[n][n];
    for (int i = 0; i < n; i++) {
        int a_num = rand.nextInt(n);
        for (int j = 0; j < a_num; j++) {
            input[i][j] = 'a';
        }
        for (int j = a_num; j < n; j++) {
            input[i][j] = 'b';
        }
    }       
    System.out.println(Arrays.deepToString(input));     
    System.out.println(acount(input));

}

}

How can it resolved?

Okay, let's start with your original version.

public static int acount(char[][] mat) {
    int result = 0;

    int i = 0;
    int j = 0;

    while (i <= 4) {
        if (mat[i][j] == 'a') {
            result++;
            j++;
        }
        if (mat[i][j] == 'b') {
            i++;
            j = 0;
        }
    }
    return result;
}

This code looks problematic. First, it assumes that your input only contains a or b. If you include other data, you'll never increment either i or j and you loop forever. It also looks like you're assuming that each row in the matrix is aab-who-cares. That is, all a's, but you stop looking at the first b. Is that what you really want? Maybe it is.

I would have written this as:

for (int index1 = 0; index1 < 5; ++index1) {
     for (int index2 = 0; index2 < 5; ++index2) {
         if (mat[index1][index2] == 'a') {
             ++result;
         }
     }
}

And actually, i wouldn't hard-code 5 but would instead use mat.length and mat[index1].length respectively.

As for your stack overflow -- this is because your recursion never ends. You do this:

    return acount(mat);

That is, you call acount with the same array again, which calls acount again, which calls acount again...

The only way that doesn't fail is if your code above returns early, which it probably won't. I think what you're missing is that each time you enter acount , you get fresh variables, so i and j start out freshly as zeros again.

You could partially solve this by passing i into acount , and when you recurse:

return acount(mat, i+1);

That will fix some of the problem, although I think you're complexity is still O(n^2).

Then let's look at this:

while (mat[i][j] == 'a') {
    result++;
    j++;
}

What happens if the row never has any a's in it? It looks past the end of the array. You're making assumptions about the input data, which is going to bite you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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