内螺旋和外螺旋自然序列的实现

来源:互联网 发布:网络词笔芯是谁发明 编辑:程序博客网 时间:2024/05/29 13:10

内螺旋和外螺旋:

所谓内螺旋序列:从1开始的自然数由方阵的外围向内螺旋方式地顺序排列。表现形式:
1    2   3   4  
12 13 14 5
11 16 15 6
10  9   8   7
外螺旋序列:从内向外螺旋方式顺序地排列。表现形式:
10 11 12 13 
 9   2   3   14 
 8   1   4   15 
 7   6   5  1 6 
要求:编程实现在控制台打印,输入N,就能打印相应的N*N方阵的螺旋序列。

思路:

不管是内螺旋还是外螺旋,都先将其装入到一个N*N的二维数组中,而二维数组的坐标是固定的,遍历二维数组也是用双循环,一行行顺序顺序遍历。
于是,打印内螺旋,只需按着外螺旋的走向遍历二维数组,申请一个公共的数,一直保持递增,将其值存入二维数组中,再打印出二维数组即可。

打印外螺旋,需要借助层的思想:将1规定为第0层。那么第一层的数据就是 2 - 9,第二层的数据是 10 - 25……也就是说第N层内有(2N-1)^2个数。
每一层分为上、下、左、右。四个数列组成,找到每个数列与所在导数的关系。然后正常遍历二维数组,依次判断数组坐标所在的层数,根据关系算出值存入对象坐标的二维数组中,再正常遍历打印出二维数组即可。这里判断四个方向的数列有个技巧:先判断左右数列,再判断上下数列,这样右上角的数就会被判断到符合左右数列的值中,不会出错。

代码实现:

public class Test9 {public static void main(String[] args) {// TODO Auto-generated method stub// 打印4*4内螺旋数组// printArr(insideSpin(4),4);// 打印5*5外螺旋数组printArr(outsideSpin(5), 5);}// 外螺旋数组public static int[][] outsideSpin(int n) {int[][] arr = new int[n][n];// 以层的思想思考:第0层的数是 1, 第1层的数是 2-9, 第2层的数是 10 - 25;// 先判断二维数组的坐标所在层数,再根据规律赋值// 判断n为奇数的情况if (n % 2 == 1) {for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {int y = i - n / 2; // 纵坐标int x = j - n / 2; // 横坐标int t = max(x, y); // t就是当前坐标所在层// System.out.print("("+ x + ","+ y +")");//调试,看坐标判断对不对// System.out.print(t+" "); //调试,看层数判断对不对int u = t + t;int v = u - 1;v = v * v + u; // v = (2t-1)^2 + 2t// 每一层都有4个方位,分为上下左右,右要在上先判断,因为要将右上角的元素划到右列才符合规律if (arr[i][j] == 0) {if (x == -t) { // 左arr[i][j] = v + 5 * t - y; // (2t-1)^2 + 7t - y;} else if (x == t) { // 右arr[i][j] = v + t + y; // (2t-1)^2 + 3t + y;} else if (y == -t) { // 上arr[i][j] = v - t + x; // (2t-1)^2 + t + x;} else { // 下arr[i][j] = v + 3 * t - x; // (2t-1)^2 + 5t - x;}}}// System.out.println();}} else {// 判断n为偶数的情况,横坐标得向右移,即j=1开始循环,但数组还得回归到本来坐标赋值for (int i = 0; i < n; i++) {for (int j = 1; j < n + 1; j++) {int y = i - n / 2; // 纵坐标int x = j - n / 2; // 横坐标int t = max(x, y); // t就是当前坐标所在层// System.out.print("("+ x + ","+ y +")");//调试,看坐标判断对不对// System.out.print(t+" "); //调试,看层数判断对不对int u = t + t;int v = u - 1;v = v * v + u; // v = (2t-1)^2 + 2t// 每一层都有4个方位,分为上下左右,右要在上先判断,因为要将右上角的元素划到右列才符合规律if (arr[i][j-1] == 0) {if (x == -t) { // 左arr[i][j-1] = v + 5 * t - y; // (2t-1)^2 + 7t - y;} else if (x == t) { // 右arr[i][j-1] = v + t + y; // (2t-1)^2 + 3t + y;} else if (y == -t) { // 上arr[i][j-1] = v - t + x; // (2t-1)^2 + t + x;} else { // 下arr[i][j-1] = v + 3 * t - x; // (2t-1)^2 + 5t - x;}}}}}return arr;}// 判断第几层private static int max(int a, int b) {a = (a) >= 0 ? a : (-a);b = (b) >= 0 ? b : (-b);a = a > b ? a : b;return a;}// 内螺旋数组public static int[][] insideSpin(int n) {int[][] arr = new int[n][n];int m = 1;// 以m增长的形式来依次判断m所在的坐标,并填入数值mfor (int i = 0; i < n / 2; i++) {for (int j = 0; j < n - i; j++) {if (arr[i][j] == 0)arr[i][j] = m++;}for (int j = 0; j < n - i; j++) {if (arr[j][n - i - 1] == 0)arr[j][n - i - 1] = m++;}for (int j = n - i - 1; j > i; j--) {if (arr[n - i - 1][j] == 0)arr[n - i - 1][j] = m++;}for (int j = n - i - 1; j > i; j--) {if (arr[j][i] == 0)arr[j][i] = m++;}}if (arr[n / 2][n / 2] == 0)arr[n / 2][n / 2] = m;return arr;}/** * @param arr *            需要打印的数组 * @param n *            n*n数组的参数 *///按照对齐的格式打印二维数组,如果值大于100,再另作格式。public static void printArr(int[][] arr, int n) {for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (arr[i][j] > 0 && arr[i][j] < 10)System.out.print(arr[i][j] + "  ");else if (arr[i][j] >= 10 && arr[i][j] < 100)System.out.print(arr[i][j] + " ");}System.out.println();}}}


0 0
原创粉丝点击