黑马程序员技术交流社区
标题:
今天遇到一个问题,调了一个下午,跟大家分享一下吧。
[打印本页]
作者:
暗影流光
时间:
2014-7-13 17:21
标题:
今天遇到一个问题,调了一个下午,跟大家分享一下吧。
问题描述:
打印等长的二维数组,要求从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列。
如: n = 4 则打印:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
代码:
package com.java;
public class PrintFangZhen {
/**
* 打印等长的二维数组,要求从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列。 如: n = 4 则打印:
* 1 2 3 4
* 12 13 14 5
* 11 16 15 6
* 10 9 8 7
*
*/
public static void main(String[] args) {
int n = 4;
if (n <= 0) {
System.out.println("n必须大于0!");
return;
}
int[][] arr = method(n);
traverse(arr);
}
/**
* 按从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列,并存到一个二维数组中
*
* @param n
* 这个方阵的边长
* @return 一个二维数组
*/
public static int[][] method(int n) {
// 定义一个储存数字的二维数组
int[][] arr = new int[n][n];
// 定义一个count计数,count即为数组中的元素
int count = 0;
int i = 0, j = 0;
while (true) {
// 当n为1的时候,直接存入数组中并结束循环
if (n == 1) {
arr[0][0] = 1;
break;
}
// 当一个元素的上、右、下、左的值不是0的时候;或者是当其上和右有值,并且左和下越界时,结束循环
if ((i - 1 >= 0 && j + 1 <= n - 1 && i + 1 <= n - 1 && j - 1 >= 0
&& arr[i - 1][j] != 0 && arr[i][j + 1] != 0
&& arr[i + 1][j] != 0 && arr[i][j - 1] != 0)
|| (j - 1 < 0 && i + 1 > n - 1 && arr[i - 1][j] != 0 && arr[i][j + 1] != 0)) {
break;
}
// 如果上面的角标越界了,并且右面的角标没越界,则向右移动
if ((i - 1 < 0 && j <= n - 1)) {
arr[i][j++] = ++count;
} else if (j + 1 > n - 1 && i + 1 <= n - 1) {
// 如果右面的角标越界了,并且下面的角标没越界,则向下移动
if (j == n) {
j--;
}
i++;
arr[i][j] = ++count;
} else if (i + 1 > n - 1 && j - 1 >= 0) {
// 如果下面的角标越界了,并且左边的角标没越界,则向左移动
arr[i][--j] = ++count;
} else if (j - 1 < 0 && i - 1 >= 0 && arr[i - 1][j] == 0) {
// 如果左边的角标越界了,并且上边的角标没越界,并且上边的元素的值为0,则向上移动
arr[--i][j] = ++count;
} else {
// 如果不是边缘,则按其他情况来计算
if (arr[i - 1][j] != 0 && arr[i][j + 1] == 0) {
// 如果右面元素的值为0,并且上面元素的值不为0,则向右移动
arr[i][++j] = ++count;
} else if (arr[i + 1][j] == 0) {
// 如果下面元素的值为0,则向下移动
arr[++i][j] = ++count;
} else if (arr[i][j - 1] == 0) {
// 如果左面元素的值为0,则向左移动
arr[i][--j] = ++count;
} else if (arr[i - 1][j] == 0) {
// 如果上面元素的值为0,则向上移动
arr[--i][j] = ++count;
}
}
}
return arr;
}
/**
* 遍历二维数组
*
* @param arr
* 一个待遍历的二维数组
*/
public static void traverse(int[][] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
复制代码
如果大家还有更好的方法,欢迎交流。
作者:
001可望成功
时间:
2014-7-13 17:25
就是蜗牛呗,记得以前用C语言写,当时还没做出来
作者:
GoodBoy123
时间:
2014-7-13 17:25
我表示完全看不懂是什么意思
作者:
乐此不疲
时间:
2014-7-13 18:18
好复杂啊
作者:
Bukeng
时间:
2014-7-13 18:26
这是入学考试题吧
作者:
Caincxy
时间:
2014-7-13 18:35
学习下啊...
作者:
黎志勇
时间:
2014-7-13 19:56
本帖最后由 黎志勇 于 2014-7-13 20:02 编辑
试着写了下。
package test;
public class Test8 {
private final static int RIGHT = 0, DOWN = 1, LEFT = 2, UP = 3;// 定义方向常量
public static void main(String[] args) {
printArray(10);
}
public static void printArray(int length) {
int direction = RIGHT;// 移动方向
int[][] array = new int[length][length];// 注意,整形数组元素默认值是0,值为0即未被填充
// row、col为将要填充数据的行号和列号
for (int i = 1, row = 0, col = 0; i <= length * length; i++) {
array[row][col] = i;
// 根据方向,确定下一个填充数据的坐标的位置
switch (direction) {
case RIGHT:
// 当右边不越界,且右边位置的值为0时,指针向右移动
if (col + 1 < length && array[row][col + 1] == 0) {
col++;// 列号增加表示指针右移
} else {// 否则更改方向,向下移动
direction = DOWN;
row++;// 行好增加表示向下移动
}
break;
case DOWN:// 其他方向类似,右→下,下→左,左→上,上→右
if (row + 1 < length && array[row + 1][col] == 0) {
row++;
} else {
direction = LEFT;
col--;
}
break;
case LEFT:
if (col - 1 > -1 && array[row][col - 1] == 0) {
col--;
} else {
direction = UP;
row--;
}
break;
case UP:
if (row - 1 > -1 && array[row - 1][col] == 0) {
row--;
} else {
direction = RIGHT;
col++;
}
break;
}
}
print(array);// 打印数组
}
private static void print(int[][] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j] + "\t");
}
System.out.println();
}
}
}
复制代码
作者:
idency
时间:
2014-7-13 20:16
我也有这个题,这是我的做法,略显麻烦!:L
package com.itheima;
/**
* 写一方法,打印等长的二维数组,要求从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列。 如: n = 4 则打印:
* 1 2 3 4
* 12 13 14 5
* 11 16 15 6
* 10 9 8 7
*
*思路:
*1.定义一个二维数组,请arr用来接收要打印的数据
*2.打印该螺旋方式,可以将螺旋看成是多次循环,每次循环的开始位置都是a[0][0] a[1][1] a[2][2]...
*3.只需根据给定的n的值确定循环次数即可,循环次数为(n+1)/2
*4.另外需要确定每次开始位置的值,随后按照螺旋顺序让对应角标值递增即可
*5.遍历数组并按要求打印
*
*
*/
public class Test9 {
public static void main(String[] args) {
//定义变量n用来表示需要打印的数组的大小
int n = 15;
//定义print()方法,用来完成数组内容的确定并打印
print(n);
}
public static void print(int n) {
//定义一个int型数组,用来接收需要打印的数据
int[][] arr = new int[n][n];
//定义int型变量count,用来表示螺旋数组循环的次数
int count = (n + 1) / 2;
//确定每个循环开始出的初始值a[0][0] a[1][1] a[2][2]...
arr[0][0] = 1;
for (int i = 1; i < count; i++) {
arr[i][i] = arr[i - 1][i - 1] + ((n - (i - 1) * 2) * 2 - 2) * 2;
}
//使用for循环,依次循环确定每次回环上的对应角标的值
for (int i = 0; i < count; i++) {
//该循环用于确定每次回环上上边缘数据
for (int j = i + 1; j < arr.length - i; j++) {
arr[i][j] = arr[i][j - 1] + 1;
}
//该循环用于确定每次回环上右边缘的数据
for (int j = i + 1; j < arr.length - i; j++) {
arr[j][arr.length - i - 1] = arr[j - 1][arr.length - i - 1] + 1;
}
//该循环用于确定每次回环上下边缘的数据
for (int j = arr.length - i - 2; j >= 0 + i; j--) {
arr[arr.length - i - 1][j] = arr[arr.length - i - 1][j + 1] + 1;
}
//该循环用于确定每次回环上左边缘的数据
for (int j = arr.length - i - 2; j > 0 + i; j--) {
arr[j][i] = arr[j + 1][i] + 1;
}
}
//使用for循环获得一维数组
for (int i = 0; i < arr.length; i++) {
int[] js = arr[i];
//使用for循环获取每个一维数组中的元素,并按要求打印
for (int j = 0; j < js.length; j++) {
System.out.print(js[j] + "\t");
}
//每次打印完成一个一维数据后进行换行
System.out.println();
}
}
}
复制代码
作者:
╰_〃无法释怀的
时间:
2014-7-13 20:27
顶一下!!!
作者:
暗影流光
时间:
2014-7-14 11:01
Bukeng 发表于 2014-7-13 18:26
这是入学考试题吧
是的。:)
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2