Java笔记(例1:蛇形填数) 边走边聊

(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 !

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值