(2013-7-17)
今天先复习一下昨天的成果,来一道小小的设计题---蛇形填数:
在n*n的方阵中填入1,2,...,n*n;要求填成蛇形。例如n=4时的方阵为:
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
上面的方阵中,多余的空格只是为了便于观察规律,不必严格输出。n <= 8。
分析:
小汪汪,就是要填成如下图所示哦:
想要实现的目标就是上图蓝色的线画出来的顺序来填充这个16宫格(4×4);
怎么实现呢?小汪汪自己先思考一下哦!
........................................................................................................................
因为控制台打印是从左到右,从上到下的,不可以反复;我们发现,如果要在控制台上直接输出这种规律的数,需要我们找到一个公式,或者对应关系,当n的大小确定后,各个位置比如(0,0)坐标处对应的数,这个似乎比较难找呀,不过可以思考一下试着找找看噻!
这里我们想到可以先不直接打印到控制台上,可以先打印到一个数组中,然后再将数组中的数依次打印到控制台上,这样就解决了控制台打印不可以反复的限制;
再来分析一下向一个二维数组中打印该蛇形数字的规律:
首先是数组的最外一圈打印(以n=4为例):下下下下,左左左,上上上,右右
然后是数组的内圈:下下,左,上;结束
如果数组更大一些的话,打印的顺序一定是从数组的外圈向内圈,方向顺序就是:下 -> 左 -> 上 -> 右
判断条件有两个:1、数组不可以越界,不要打印到数组的外面 2、已经被打印过的位置不要再打印了(这一点可以将数组所有位置一开始全赋值为0,检查到非零的位置就可以确定是打印过的)
代码如下:
/********************************
*
* Example 1
* @author xiaosu.wang
*
********************************/
import java.util.Scanner;
public class sShapedCounting
{
private int n;
sShapedCounting(int m)
{
try
{
if(m<1 || m>8)
throw new IllegalArgumentException("n shouldn't like this!");
n = m;
}
catch(IllegalArgumentException ex)
{
System.out.println("n should be an integer, between one and eight!");
}
}
public void print_sShapedCounting()
{
int[][] sShapedArray = new int[n][n];
for(int i=0;i!=n;++i)
for(int j=0;j!=n;++j)
sShapedArray[i][j]=0;
int row = -1;
int column = n;
int count = 1;
while(count <= n*n)
{
++row;
--column;
while(row < n && sShapedArray[row][column] == 0)
{
sShapedArray[row][column] = count;
++count;
++row;
}
--row;
--column;
while(0 <= column && sShapedArray[row][column] == 0)
{
sShapedArray[row][column] = count;
++count;
--column;
}
++column;
--row;
while(0 <= row && sShapedArray[row][column] == 0)
{
sShapedArray[row][column] = count;
++count;
--row;
}
++row;
++column;
while(column < n && sShapedArray[row][column] == 0)
{
sShapedArray[row][column] = count;
++count;
++column;
}
}
for(int i=0;i!=n;++i)
{
for(int j=0;j!= n;++j)
System.out.printf("%3d",sShapedArray[i][j]);
System.out.println();
}
}
public static void main(String []args)
{
System.out.print("Enter one integer:");
Scanner input = new Scanner(System.in);
int m = input.nextInt();
input.close();
sShapedCounting sShaped = new sShapedCounting(m);
sShaped.print_sShapedCounting();
}
}
上面的代码第36到76行可以更简洁的写为如下代码:
int row = -1;
int column = n-1;
int count = 1;
while(count <= n*n)
{
while(row+1 < n && sShapedArray[row+1][column] == 0)
{
sShapedArray[++row][column] = count++;
}
while(0 <= column-1 && sShapedArray[row][column-1] == 0)
{
sShapedArray[row][--column] = count++;
}
while(0 <= row-1 && sShapedArray[row-1][column] == 0)
{
sShapedArray[--row][column] = count++;
}
while(column+1 < n && sShapedArray[row][column+1] == 0)
{
sShapedArray[row][++column] = count++;
}
}
运行效果如下图:
Little wangwang, I miss you !