二维数组螺旋算法中的逻辑错误
Logical error in 2d array spiral alorithm
我正在尝试用二维数组制作螺旋线。但是我缺少最后一个元素,如图所示。
.
我试图在 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();
}
我想要的输出:
我试过类似的东西:
while(top <= bottom +/- 1 && left <= right +/- 1 )
while(top <= bottom +/- 2 && left <= right +/- 2)
while(bottom - top >= 0 && right - left >=0 )
还有很多,但结果与上图一样。
原因是你在更新边界变量(top
、left
、right
、bottom
)时一步为二,你仍然当你开始你的下一个方向时,需要填写一个 outside 的单元格(这就是你做 two blankGrid
作业的原因在内部循环的每次迭代中——这看起来很奇怪)。只要 while
条件为真,这就没有问题,但在最后一个阶段,该条件将为假,这意味着“框”已缩小为空。然而还有这个细胞要放置...
一个解决方案是不使用 2 更改该边界,而只更改 1,然后在您从下一个方向开始时执行另一个 increment/decrement。
你的循环体可以用这个想法更新如下:
//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 个代码块很相似,可以合并为一个。但这与问题无关,留待大家改进。
我正在尝试用二维数组制作螺旋线。但是我缺少最后一个元素,如图所示。
我试图在 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();
}
我想要的输出:
我试过类似的东西:
while(top <= bottom +/- 1 && left <= right +/- 1 )
while(top <= bottom +/- 2 && left <= right +/- 2)
while(bottom - top >= 0 && right - left >=0 )
还有很多,但结果与上图一样。
原因是你在更新边界变量(top
、left
、right
、bottom
)时一步为二,你仍然当你开始你的下一个方向时,需要填写一个 outside 的单元格(这就是你做 two blankGrid
作业的原因在内部循环的每次迭代中——这看起来很奇怪)。只要 while
条件为真,这就没有问题,但在最后一个阶段,该条件将为假,这意味着“框”已缩小为空。然而还有这个细胞要放置...
一个解决方案是不使用 2 更改该边界,而只更改 1,然后在您从下一个方向开始时执行另一个 increment/decrement。
你的循环体可以用这个想法更新如下:
//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 个代码块很相似,可以合并为一个。但这与问题无关,留待大家改进。