简体   繁体   中英

Java 2D Array Spiral/Clockwise Traversal

The problem has been discussed on stackoverflow before, I'm specifically asking for opinion or answers regarding my code and whether or not it can work with imbalanced 2d arrays without a major overhaul. The reason it's failing to print the end of some balanced arrays must be some smaller issue. Update at the bottom

Basically we have a 2d array supplied by a command line driven text file. That file has each trial separated by a newline and follows like this: rows;columns;values(white space delimited)

Example: 4;4;1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

Output: 1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package spiralprinting;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 *
 * @author Paul
 */
public class SpiralPrinting {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws FileNotFoundException, IOException {
        // TODO code application logic here
        File file = new File(args[0]);
        BufferedReader in = new BufferedReader(new FileReader(file));
        String line;
        while ((line = in.readLine()) != null) {

            String[] lineArray = line.split(";");
            if (lineArray.length > 0) {//ignore blank line inputs
                //Process line of input Here

                //Max ,minimum, and current indexes in our matrix.
                int maxX = Integer.parseInt(lineArray[0]) - 1;
                int maxY = Integer.parseInt(lineArray[1]) - 1;
                int minX = 0;
                int minY = 0;
                int x = 0;
                int y = 0;

                //Build our matrix
                String[] valueArray = lineArray[2].split("\\s");
                String[][] matrix = new String [Integer.parseInt(lineArray[0])][Integer.parseInt(lineArray[1])];
                int count = 0;

                for (int j = 0; j <= maxY; j++){
                    for (int i = 0; i <= maxX; i++){
                        matrix[i][j] = (valueArray[count]);
                        count++;
                    }
                }

                StringBuilder printString = new StringBuilder();
                //Traverse and print our matrix in a spiral!
                while (maxX > minX && maxY > minY){
                    //Leaving this in and commented so you can see my train of thought.

                    if (x != maxX){
                        while (x < maxX){
                            printString.append(matrix[x][y]).append(" ");
                            x++;
                        }maxX--;
                    }
                    if (y != maxY){
                        while (y < maxY){
                            printString.append(matrix[x][y]).append(" ");
                            y++;
                        }maxY--;
                    }
                    if (x != minX){
                        while (x > minX){
                            printString.append(matrix[x][y]).append(" ");
                            x--;
                        }minX++;
                    }
                    if (y != minY){
                        while (y > minY){
                            printString.append(matrix[x][y]).append(" ");
                            y--;
                        }minY++;
                    }
                    //One border done (4 passes). Next iteration of while-loop begins.
                    x = minX;
                    y = minY;
                }//end of our traversal loop
                //Print it !
                System.out.println(printString.toString().trim());
            }
        }//end of input line analysis
    }
}//end of class

Sample input and current output:

4;4;1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ---> 1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10 good

3;3;1 2 3 4 5 6 7 8 9 ---> 1 2 3 6 9 8 7 4 This fails to print the 5

3;4;1 2 3 4 5 6 7 8 9 10 11 12 ---> 1 2 3 6 9 12 11 10 7 4 ..fails to print the 5, 8 at the end...

4;3;1 2 3 4 5 6 7 8 9 10 11 12 ---> 1 2 3 4 8 12 11 10 9 5 ..fails to print the last 2 again: 6, 7"

2;10;1......20 ---> 1, 2, 4, 6, 8.... good

After some quick revisions, my issue appears to be that it is not printing the last 2 for some sets. I'm convinced this is a special case and I'm going to sleep on it :)

Any help is still appreciated, especially if you think the issue is larger than I currently believe. My sleepy brain thinks I need 2 special cases to go along with my 4 checks in the while-loop...

Thank you =]

When your debugging something and you just CANT wrap your mind around whats going wrong... break it down into something easy to debug, throw out your hard test cases and try something very simple then move up to harder ones and find where it breaks, heres how i found it.

I commented out all your code where you input the file and made your input to a fixed string:

String[] lineArray = ("3;2;" +
                           "1 2 3 " +
                           "6 5 4 ").split(";"); 
// see how the output should be 123456...very easy to see and debug

Putting a breakpoint at while (maxX > minX || maxY > minY) , I looked at the matrix array and saw that the matrix was of size 2x3 not 3x2, and my numbers were not stored how I would think they should be. And voila problem found.

/*if (maxY >= maxX){*/
    // This for loop is what you want
    for (int j = 0; j <= maxY; j++){
        for (int i = 0; i <= maxX; i++){
            matrix[i][j] = (valueArray[count]);
            count++;
        }
    }
/*}/*delete this junk/ else if (maxX > maxY){
    for (int i = 0; i <= maxX; i++){
        for (int j = 0; j <= maxY; j++){
            matrix[i][j] = (valueArray[count]);
            count++;
        }
    }
}*/

This is a fun one for recursion. I assume you already submitted your code for your project so I took a stab at it. Heres what I ended up with: (I left in the printlns so you could see the program flow)

// called by System.out.println(getSpiral(matrix,0,0,0,0));

public static String getSpiral(String[][] array, int x, int y, double direction, int turnCount) {

    int [] velocity = getDirection(direction);
    if(x+velocity[0] >= array.length || y+velocity[1] >= array[x].length ||
            x+velocity[0] < 0 || y+velocity[1] < 0 ||
            array[x+velocity[0]][y+velocity[1]].equals("done")) {
        System.out.println("turn");
        if(turnCount>=3)
            return array[x][y];
        return getSpiral(array, x, y, direction+Math.PI/2,turnCount+1);
    }
    String value = array[x][y].toLowerCase();
    array[x][y]="done";
    System.out.println(value);
    return value + " " + getSpiral(array, x+velocity[0], y+velocity[1], direction,0);
}

public static int[] getDirection(double angle) {
    return new int[] {(int)Math.round(Math.cos(angle)), (int)Math.round(Math.sin(angle))};
}

clockwise traversal

public static String matrixTraverse(int[][] matrix, int startX, int startY){
    String result = "";
    boolean baseCase = startX + 1 == Math.ceil(matrix[0].length / 2.0)
            || startY + 1 == Math.ceil(matrix.length / 2.0);

    for (int i = startX ; i < matrix[0].length - startX ; i++) {
        result += " " + matrix[startY][i];
    }

    for (int i = startY + 1 ; i < matrix.length - startY - 1 ; i++){
        result += " " + matrix[i][matrix[0].length - 1 - startX];
    }

    for (int i = startX ; (matrix.length - 1 != 2 * startY) && (i < matrix[0].length - startX) ; i++){
        result += " " + matrix[matrix.length - 1 - startY][matrix[0].length - 1 - i];
    }

    for (int i = startY  ; (matrix[0].length - 1 != 2 * startX) && (i < matrix.length - startY - 2) ; i++){
        result += " " + matrix[matrix.length - 2 - i][startX];
    }

    if (!baseCase) {
        result += matrixTraverse(matrix, ++startX, ++startY);
    }

    return result;

}

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