二维阵列螺旋算法中的逻辑错误

问题描述

我正在尝试用二维数组制作螺旋。但是我缺少最后一个元素,如图所示。

spirals example

我试图在while循环中设置各种条件以在一个循环后停止算法,但我做不到,因此我变得疯狂。主要算法代码如下:

    // height is always bigger than width by 1
    char [][] blankGrid = new char [height][width];

    int dir = 0;
    int top = 0;
    int bottom = height-1;
    int left = 0;
    int right = width-1;

    //draw digit spiral
    while(top <= bottom && left <= right ) {

        //RIGHT
        if (dir == 0) {
            for (int i = left; i <= right; i++) {
                blankGrid[top][i] = '0';
                if(left != 0 )blankGrid[top ][i-1] = '0';
                System.out.println(" DIR = 0 Position changed: "+ top   + "," + i);
            }
            top += 2;
            dir++;

            //DOWN
        } else if (dir == 1) {
            for (int i = top; i <= bottom; i++) {
                blankGrid[i][right] = '1';
                blankGrid[i-1][right] = '1';
                System.out.println(" DIR = 1 Position changed: "+ top   + "," + i );
            }
            right -= 2;
            dir++;

            //LEFT
        }else if (dir == 2) {
            for (int i = right; i >= left; i--) {
                blankGrid[bottom][i] = '2';
                blankGrid[bottom][i+1] = '2';
                System.out.println(" DIR = 2 Position changed: "+ bottom   + "," + i);
            }
            bottom -= 2;
            dir++;

            //UP
        }else if (dir == 3) {
            for (int i = bottom; i >= top ; i--) {
                blankGrid[i][left] = '3';
                blankGrid[i+1][left] = '3';
                System.out.println(" DIR = 3 Position changed: "+ top   + "," + i);
            }
            left += 2;
            dir = 0;
        }
    }

   // display  grid
    for(int i = 0; i < height; i++) {
        for(int j = 0; j < width; j ++){
            System.out.printf("%c",blankGrid[i][j]);
        }
        System.out.println();
    }

我想要的输出

desired output

我尝试了以下方法

 while(top <= bottom +/- 1 && left <= right +/- 1 )
 while(top <= bottom +/- 2 && left <= right +/- 2)
 while(bottom - top >= 0 && right - left >=0 )

还有更多,但结果与上图相同。

解决方法

原因是您仍然需要以两步更新边界变量(topleftrightbottom)当您开始下一个方向时,填充位于该框外部的一个单元格(这就是为什么您在内部循环的每次迭代中进行两次 blankGrid 赋值 - - 这看起来很奇怪)。只要 while 条件为真,这没有问题,但在最后一个阶段,该条件将为假,这意味着“盒子”已经缩小到没有。然而仍然有一个单元格要放置...

一种解决方案是不将边界更改为 2,而仅更改为 1,并在您开始下一个方向时进行另一个递增/递减。

你的循环体可以用这个想法更新如下:

        //RIGHT
        if (dir == 0) {
            for (int i = left; i <= right; i++) {
                blankGrid[top][i] = '0';
            }
            if (left > 0) left++;
            top++;
            dir++;
            //DOWN
        } else if (dir == 1) {
            for (int i = top; i <= bottom; i++) {
                blankGrid[i][right] = '1';
            }
            top++;
            right--;
            dir++;
            //LEFT
        }else if (dir == 2) {
            for (int i = right; i >= left; i--) {
                blankGrid[bottom][i] = '2';
            }
            right--;
            bottom--;
            dir++;
            //UP
        }else if (dir == 3) {
            for (int i = bottom; i >= top ; i--) {
                blankGrid[i][left] = '3';
            }
            bottom--;
            left++;
            dir = 0;
        }

我只是做了很少的改动来让它工作,但你应该尽量减少代码的重复。这4个代码块类似,可以合二为一。但由于这与问题无关,我将把它留给您改进。