连续数字的旋转二维数组

生成一个连续数字的旋转二维数组,起始位置位于左上角,然后从起始位置开始递增,按照顺时针或者逆时针从外向里将连续的数组存入二维数组中,并输出生成的旋转二维数组。

/**
*
* <code>ConvolutionalArray</code>主要是用来输出一个旋转式样的二维数组。
*
*
* 此二维数组由连续的数字组成,比如:
* *
* int i=5;
* 1 2 3 4 5
* 16 17 18 19 6
* 15 24 25 20 7
* 14 23 22 21 8
* 13 12 11 10 9

* int i=6
* 1 2 3 4 5 6
* 20 21 22 23 24 7
* 19 32 33 34 25 8
* 18 31 36 35 26 9
* 17 30 29 28 27 10
* 16 15 14 13 12 11
*

*
* @author Eric
* @version 1.0
*
*/

public class ConvolutionalArray {

private static final int DEFAULT_NUMBER = 5;

// 定义连续数字添加的方向
private enum Direction {
Right, Down, Left, Up;
}

// 保存当前处理的方向,默认一开始是向右的。
private Direction currentDirection = Direction.Right;

// 将一个二维数组看成X, Y两个方向,记录下,最小的X,Y值以及最大的X,Y
private int minX = 0;

private int minY = 0;

private int maxX = DEFAULT_NUMBER - 1;

private int maxY = DEFAULT_NUMBER - 1;

private int currentCount = 0;

/**
* 打印数组。
*
* @param expectedNumber :
* 期望的二维数组每行显示的个数。
*/
public void printArray(int expectedNumber) {
int[][] array = buildArray(expectedNumber);
printArray(array, expectedNumber);
}

/**
*
* @param expectedNumber:
* 期望的二维数组每行显示的个数。
* @return: 返回一个连续数字组成的二维数组。
*/
private int[][] buildArray(int expectedNumber) {
int[][] result = new int[expectedNumber][expectedNumber];
// Total number of numeric values
int count = expectedNumber * expectedNumber;
// Reset max value for maxX and maxY.
maxY = expectedNumber - 1;
maxX = expectedNumber - 1;
/*
* 如果要生成一个nxn的二维数组,那么里面的最大数应该是n*n, 当处理的数字还没有达到这个最大值,一直循环处理下去。
*
*/
while (currentCount < count) {
/*
* 因为开始默认的方向是Right,也就是顺时针方向,所以,处理的顺序是 Right -> Down -> Left -> Up
* ->Right ... 每次一个方向填充值之后,需要先判断当前数据是否达到最大值。
*/
if (currentCount < count) {
processRight(result);
}
if (currentCount < count) {
processDown(result);
}
if (currentCount < count) {
processLeft(result);
}
if (currentCount < count) {
processUp(result);
}
}
return result;
}

/**
* 向右方向填充数据。
*/
private void processRight(int[][] currentArray) {
for (int i = minX; i <= maxX; i++) {
currentArray[minY][i] = ++currentCount;
}
changeDirection();
minY++;
}

/**
* 向下方向填充数据。
*/
private void processDown(int[][] currentArray) {
for (int i = minY; i <= maxY; i++) {
currentArray[i][maxX] = ++currentCount;
}
changeDirection();
maxX--;
}

/**
* 向左方向填充数据。
*/
private void processLeft(int[][] currentArray) {
for (int i = maxX; i >= minX; i--) {
currentArray[maxY][i] = ++currentCount;
}
changeDirection();
maxY--;
}

/**
* 向上方向填充数据。
*/
private void processUp(int[][] currentArray) {
for (int i = maxY; i >= minY; i--) {
currentArray[i][minX] = ++currentCount;
}
changeDirection();
minX++;
}

/**
* 打印二维数组的内容。
*
* @param array
* @param expectedNumber
*/
private void printArray(int[][] array, int expectedNumber) {
for (int i = 0; i < expectedNumber; i++) {
for (int j = 0; j < expectedNumber; j++) {
System.out.print(appendSpace(array[i][j], expectedNumber));
}
System.out.println();
}
}

/**
* 为了保证数据输出时能够对齐,添加一些空格.
*/
private String appendSpace(int value, int expectedNumber) {
int maxValue = expectedNumber * expectedNumber;
int maxLength = String.valueOf(maxValue).length();
int currentValueLength = String.valueOf(value).length();
StringBuilder sb = new StringBuilder();
sb.append(value);
for (int i = maxLength; i > currentValueLength; i--) {
sb.append(" ");
}
sb.append(" ");
return sb.toString();
}

/**
* 改变当前的方向。
*/
private void changeDirection() {
switch (currentDirection) {
case Right:
currentDirection = Direction.Down;
break;
case Down:
currentDirection = Direction.Left;
break;
case Left:
currentDirection = Direction.Up;
break;
case Up:
currentDirection = Direction.Right;
break;
}
}

/**
* 在一个二维数组基础上,以对角线为对称线,实现两侧数据的交换,并返回这个交换数据后的二维数组。
*
* 这样做有一个用处:比如已经有一个向右的二维旋转数组(向右):
*
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
采用此方法之后,可以得到一个向下方向的二维旋转数组(向下)
1 12 11 10
2 13 16 9
3 14 15 8
4 5 6 7
*/
private int[][] exchangeArray(int[][] originalArray, int expectedNumber) {
int[][] exchangedArray = new int[expectedNumber][expectedNumber];
for (int i = 0; i < expectedNumber; i++) {
for (int j = 0; j < expectedNumber; j++) {
exchangedArray[i][j] = originalArray[j][i];
}
}
return exchangedArray;
}

/**
* 打印交换数据后的二维数组。
*/
public void printExchangedArray(int expectedNumber) {
int[][] array = buildArray(expectedNumber);
printArray(exchangeArray(array, expectedNumber), expectedNumber);
}
}


测试代码:

public class Test {
public static void main(String[] args) {
for (int i = 5; i < 11; i++) {
System.out.println("Direction: Right; int = " + i);
new ConvolutionalArray().printArray(i);
System.out.println();
System.out.println("Direction: Down; int = " + i);
new ConvolutionalArray().printExchangedArray(i);
System.out.println();
}
}
}


输出结果:

[img]http://dl2.iteye.com/upload/attachment/0084/8831/48ec7713-717a-3f28-b553-9cf9b0907b73.jpg[/img]

[img]http://dl2.iteye.com/upload/attachment/0084/8833/e98ef333-3fae-3dfe-a380-1c8e49955a2b.jpg[/img]

[img]http://dl2.iteye.com/upload/attachment/0084/8835/51c64120-4dc6-3dad-86ff-60891667d2b5.jpg[/img]


下面在显示一个大小为[b]34*34[/b]的旋转二维数组:

[img]http://dl2.iteye.com/upload/attachment/0084/8837/94bcf14d-113e-309b-9cd2-7f41d0e1e91f.jpg[/img]

[img]http://dl2.iteye.com/upload/attachment/0084/8839/069dc463-099d-39ab-bd47-5dd1c80ccdbc.jpg[/img]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值