Java 2D阵列螺旋/顺时针遍历

时间:2013-10-15 06:23:47

标签: java traversal multidimensional-array spiral

此问题已经在stackoverflow上讨论过,我特别询问有关我的代码的意见或答案,是否可以在不进行大修的情况下使用不平衡的2d数组。之所以如此未能打印某些平衡数组的结尾必须是一些较小的问题。 在底部更新

基本上我们有一个由命令行驱动的文本文件提供的二维数组。该文件的每个试验由换行符分隔,如下所示:rows; columns; values(white space delimited)

示例: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

/*
 * 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

样本输入和电流输出:

4; 4; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ---&gt; 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 ---&gt; 1 2 3 6 9 8 7 4 无法打印5

3; 4; 1 2 3 4 5 6 7 8 9 10 11 12 ---&gt; 1 2 3 6 9 12 11 10 7 4 ..无法在最后打印5,8 ...

4; 3; 1 2 3 4 5 6 7 8 9 10 11 12 ---&gt; 1 2 3 4 8 12 11 10 9 5 ..无法再打印最后2个:6,7“

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

经过一些快速修改后,我的问题似乎是它没有为某些套装打印最后2个。我确信这是一个特例,我准备睡觉了:)

任何帮助仍然受到赞赏,特别是如果您认为问题比我目前认为的要大。我昏昏欲睡的大脑认为我需要2个特殊情况才能在while循环中进行4次检查......

谢谢=]

2 个答案:

答案 0 :(得分:3)

当你调试一些东西时,你只是想知道什么是错误的...把它分解成易于调试的东西,丢弃你的硬测试用例并尝试一些非常简单的东西然后向上移动到更难的东西并找到哪里它打破了,继承人我是如何找到它的。

我将您输入文件的所有代码注释掉,并将输入输入到固定字符串中:

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

while (maxX > minX || maxY > minY)处设置一个断点,我查看矩阵数组,看到矩阵大小为2x3而不是3x2,我的数字没有存储,我认为它们应该如何。并且发现了瞧问题。

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

这是一个有趣的递归。我假设你已经为你的项目提交了代码,所以我对它进行了尝试。继续我最终得到的结果:(我留在了printlns,所以你可以看到程序流程)

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

答案 1 :(得分:0)

顺时针遍历

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;

}