【问题标题】:Java 2D Array Spiral/Clockwise TraversalJava 2D 数组螺旋/顺时针遍历
【发布时间】:2013-10-15 06:23:47
【问题描述】:

这个问题之前已经在 stackoverflow 上讨论过,我特意询问有关我的代码的意见或答案,以及 它是否可以在不进行大修的情况下处理不平衡的二维数组。 原因未能打印某些平衡数组的末尾一定是一些较小的问题。 底部更新

基本上,我们有一个由命令行驱动的文本文件提供的二维数组。该文件的每个 Trial 由换行符分隔,如下所示: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 ---> 1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10

3;3;1 2 3 4 5 6 7 8 9 ---> 1 2 3 6 9 8 7 4 这无法打印 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 ..最后无法打印 5, 8.. .

4;3;1 2 3 4 5 6 7 8 9 10 11 12 ---> 1 2 3 4 8 12 11 10 9 5 ..再次打印最后一个 2 失败:6、7"

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

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

仍然感谢任何帮助,特别是如果您认为问题比我目前认为的要大。我昏昏欲睡的大脑认为我需要 2 个特殊情况来配合我在 while 循环中的 4 个检查...

谢谢你=]

【问题讨论】:

    标签: java traversal multidimensional-array spiral


    【解决方案1】:

    当您调试某些东西时,您只是想不出哪里出了问题...将其分解为易于调试的东西,扔掉您的困难测试用例并尝试一些非常简单的东西,然后转向更难的测试用例并找到哪里它坏了,这是我找到它的方法。

    我注释掉了你输入文件的所有代码,并将你的输入变成了一个固定的字符串:

    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 &gt; minX || maxY &gt; 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))};
    }
    

    【讨论】:

    • 感谢您的浏览。看起来好像我在考虑初始化。我已经编辑了我的帖子以反映当前的问题。我当然会在可能的情况下花更多时间进行调试,如果我弄明白了,我会更新,但我仍然希望有人能看到肯定是个大问题。它仍然无法在 3 x 4 数组上打印最后一个数字“5”,当我提交给 codeeval 自动评分器时,它得到 10% :-(.
    • @spacecadet 如果你有一个 3x3 的正方形并且做了整个边框。您的 minX 将从 0 开始,maxX 从 2 开始。快进 1 个边界循环,您的 miX=1,maxX=1,x=1... 您的 while 循环会再次运行吗?不,它不会,这仅适用于正方形,并且仅当它到达中心时才会出现,因为它已将其缩小到 1x1 正方形。使固定?如果它是一个方阵,则将该代码组合在一起并将该中心数字放在最后:) 祝你好运,上帝的速度。
    • 这确实有点帮助!那里有一个问题,源于最大值等于最小值。基本上它在数组平衡时触发,但似乎有奇数个元素。我的解决方法是保留一个附加元素的计数器,如果它小于最后的总数,则附加在中位数 X+1 中位数 Y+1 上。这完美地解决了我的测试用例。虽然它在自动分级机中的表现略好一些,从 10% 到 30%。叹息@_@
    【解决方案2】:

    顺时针遍历

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-26
      • 2019-12-25
      • 2010-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多