views:

250

answers:

2

This is NOT a homework. I'm a beginner in programming, and also this is my first post here - please bear with me.

I was not able to find similar questions posted here.

In a beginner's book, I found the following issue:

# Find the biggest area of adjacent numbers in this matrix:
1 3 2 2 2 4
3 3 3 2 4 4
4 3 1 2 3 3 #--> 13 times '3'
4 3 1 3 3 1
4 3 3 3 1 1

Here's the code I have so far, using the DFS implementation from http://www.algolist.net/Algorithms/Graph_algorithms/Undirected/Depth-first_search. There are 'magic numbers' everywhere, and the methods are 'public static', etc. - I was intending to fix these things after the algorithm worked...

public class AdjacentAreaInMatrix {
    /*
     * Enums for the state of the Nodes, for use in DFS/BFS
     */
    private enum NodeState {
        Visited, InProgress, Unvisited
    }; 

    /*
     * These 2 'magic' numbers come from the hardcoded 'matrix' below,
     * cause it has 5 rows and 6 columns
     */
    public static final int ROWSCOUNT = 5;
    public static final int COLUMNSCOUNT = 6;

    /*
     * Two variables for counting the maximum sequence 
     * of numbers (as required by the problem definition)
     */
    private static int tempElementsCount = 0;
    private static int maxElementsCount = 1; // except if the matrix is empty, then it should be 0

    /*
     * The hardcoded matrix
     */
    private static final int[][] matrix = new int[][] { 
            { 1, 3, 2, 2, 2, 4 },
            { 3, 3, 3, 2, 4, 4 }, 
            { 4, 3, 1, 2, 3, 3 },
            { 4, 3, 1, 3, 3, 1 }, 
            { 4, 3, 3, 3, 1, 1 } };

    /* 
     * Create an auxiliary matrix 'state' to implement DFS. 
     * Initialize the whole matrix as 'unvisited' and
     * start DFS at the first element of the matrix
     */
    public static void DFS() {
        NodeState state[][] = new NodeState[ROWSCOUNT][COLUMNSCOUNT];
        // clear the state of the matrix
        for (int i = 0; i LT ROWSCOUNT; i++) {
            for (int j = 0; j LT COLUMNSCOUNT; j++) {
                state[i][j] = NodeState.Unvisited;
            }
        }
        runDFS(0, 0, state);    
    }

    /*
     * Using the auxiliary matrix "state[][]", use DFS to traverse the
     * 'real' matrix[][] 
     */
    public static void runDFS(int i, int j, NodeState state[][]) {
        state[i][j] = NodeState.InProgress;
        // traverse the whole matrix state[][] and recursively run runDFS() from the needed elements. 
        for (int rows = 0; rows LT ROWSCOUNT; rows++) {
            for (int columns = 0; columns LT COLUMNSCOUNT; columns++) {
                /*
                 * ----------------------------------------------------------------------
                 * For the logic in the 'if' statement regarding the adjacent elements:
                 * i0j0 i1j0 i1j0
                 * i0j1 i1j1 i2j1
                 * i0j2 i1j2 i2j2
                 * It uses the thing, that the sum of (i+j) for the coordinates of
                 * the elements above, below, on the left and on the right of i1j1
                 * are exactly +1/-1 of the sum of the coordinates of i1j1
                 * -> i1j2 to 1+2 = 3 
                 * -> i2j1 to 1+2 = 3 
                 * -> i1j1 to 1+1 = 2 (the current element) -> matrix[i][j] 
                 * -> i1j0 to 1+0 = 1 
                 * -> i0j1 to 1+0 = 1 
                 * ----------------------------------------------------------------------
                 */
                if ((matrix[i][j] == matrix[rows][columns]) // if the values are equal
                        && ((((i+j) - (rows + columns)) == 1) || (((i+j) - (rows + columns)) == -1))// and if the element is adjacent
                        && (state[rows][columns] == NodeState.Unvisited)) { // and if the element is still not visited
                    tempElementsCount++;
                    if (tempElementsCount > maxElementsCount) {
                        maxElementsCount = tempElementsCount;
                    }
                    runDFS(rows, columns, state); // recursively run DFS for each element, that "isEdge"
                } else {
                    // if the elements aren't [adjacent, equal and not visited], start the count again from '0'
                    tempElementsCount = 0;  
                }
            }
        }
        state[i][j] = NodeState.Visited;
    }

    public static void go() {
        AdjacentAreaInMatrix.DFS();
        System.out.println(maxElementsCount);
    }
}  

After debugging it for several days, with every debugging session the code becomes more complicated...any help will be appreciated. Thanks in advance.

+2  A: 

I think the problem is that you are resetting the tempElementsCount every time. Just imagine how your code would work on the given matrix and you'll see that you in the runDFS() method you always start the search with element (0, 0) for which the if clause will be false, so you reset tempElementsCount before you could continue the search with the other (and probably adjacent) elements. Hope I was clear enough...

Thanks, you were right. Starting it from (1,1) without resetting the tempElemetsCount gave 12, which is clear enough in order to making the algorithm work fine. Thanks a lot!
Adrian Nackov
Sorry, but I'm not able to vote up this answer, because I don't have enough reputation for doing that. Thanks for your help, once again.
Adrian Nackov