A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 陈圳 高级黑马   /  2013-4-9 18:45  /  2597 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 陈圳 于 2013-4-10 09:35 编辑
  1. public class Retangle {

  2.         /**螺旋矩阵数组.
  3.          * @param args
  4.          */
  5.         public static void main(String[] args) {
  6.                 int[][] arr=retangleArrays(11);//任一奇数的螺旋矩阵
  7.          for(int i=0;i<arr.length;i++){
  8.                         for(int j=0;j<arr[i].length;j++)
  9.                                 System.out.print(arr[i][j]+"    ");//大了格式就乱了.
  10.           System.out.println();
  11.                 }
  12.         }
  13.         public static int[][] retangleArrays(int num){
  14.                 if(num%2==0)//如果输入的数值不是奇数的,就跳出
  15.                         return null;
  16.                 int arr[][]=new int[num][num];
  17.                 int index=num/2;//取得数组最中间的值
  18.                 int rows=index;//二维的横坐标
  19.                 int cols=index;//二维的纵坐标
  20.                 int fixRow=index-1;//内层循环的值最小
  21.                 int fixCol=index+1;//内层循环的值最小
  22.                 arr[rows][cols]=1;
  23.                 for(int i=2;i<=arr.length*arr.length;){
  24.                         if(cols==fixRow&&rows==fixRow){//当走到小边缘的时候,就扩大其运转范围
  25.                                 if(fixRow!=0){
  26.                                         fixRow--;
  27.                                         fixCol++;
  28.                                 }
  29.                         }
  30.                         if(cols<=fixCol&&rows<=fixCol){
  31.                                 if(cols<fixCol){
  32.                                         cols++;
  33.                                         arr[rows][cols]=i;
  34.                                         i++;
  35.                                 }else{
  36.                                         rows++;
  37.                                         arr[rows][cols]=i;
  38.                                         i++;
  39.                                 }
  40.                         }
  41.                         if(cols==fixCol&&rows==fixCol){//当走到最大边缘的时候
  42.                                 for(int j=0;j<fixCol*2+1;j++){
  43.                                         if(cols>fixRow){
  44.                                                 cols--;
  45.                                                 arr[rows][cols] = i;
  46.                                                 i++;
  47.                                         }        else if(rows>fixRow){
  48.                                                         rows--;
  49.                                                         arr[rows][cols] = i;
  50.                                                         i++;
  51.                                                 }
  52.                                 }
  53.                         }
  54.                 }
  55.                 return arr;
  56.         }
  57. }
  58. 用一种比较笨的方式实现了这个,但是感觉很麻烦,并且在部分运算的时候很容易绕晕.有没有人有更好的算法?
复制代码

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

9 个回复

倒序浏览

回帖奖励 +50

我只能说 System.out.print(arr[i][j]+"    ");//大了格式就乱了.  这个地方 换成 \t  会好看点

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
第一次听说螺旋数组,有意思啊
回复 使用道具 举报
本帖最后由 蓝色骨头 于 2013-4-9 20:25 编辑

试着写了一个思路如下:
四个顶点确定一层,每次顺时针处理一层。
螺旋矩阵最后剩下一行、一竖、一点、或没有。
代码:
public class Test {
        /*
         * 四个顶点确定一层,每次顺时针处理一层。
         * 螺旋矩阵最后剩下一行、一竖、一点、或没有。
         */
        public static int[][] spiralMatrix(int m, int n){
                if(m < 1 || n < 1){
                        return null;
                }
       
                class Point{
                        Point(int x, int y){
                                this.x = x;
                                this.y = y;
                        }
                        int x,y;
                }
               
                int[][] matrix = new int[m][n];
                //four point       
                Point topLeft = new Point(0,0);
                Point topRight = new Point(0,n-1);
                Point bottomLeft = new Point(m-1,0);
                Point bottomRight = new Point(m-1,n-1);
               
                int count = 0;
                while((topRight.y - topLeft.y >= 1) && (bottomLeft.x - topLeft.x >= 1)){
                        //clockwise
                        for(int i = topLeft.y; i <= topRight.y; i++){
                                matrix[topLeft.x] = ++count;
                        }
                        for(int i = topRight.x + 1; i <= bottomRight.x - 1; i++ ){
                                matrix[topRight.y] = ++count;
                        }
                        for(int i = bottomRight.y; i >= bottomLeft.y; i--){
                                matrix[bottomRight.x] = ++count;
                        }
                        for(int i = bottomLeft.x - 1; i >= topLeft.x + 1; i--){
                                matrix[bottomLeft.y] = ++count;
                        }
                       
                        topLeft.x++; topLeft.y++;
                        topRight.x++; topRight.y--;
                        bottomLeft.x--; bottomLeft.y++;
                        bottomRight.x--; bottomRight.y--;               
                }
               
                //a line(horizontal or vertical) or a point or nothing left
                if(topRight.y - topLeft.y >= 1){
                        for(int i = topLeft.y; i <= topRight.y; i++){
                                matrix[topLeft.x] = ++count;
                        }
                }else if(bottomLeft.x - topLeft.x >= 1){
                        for(int i = topLeft.x; i <= bottomLeft.x; i++){
                                matrix[topLeft.y] = ++count;
                        }
                }else if(topLeft.x == topRight.x && topLeft.y == topRight.y && topLeft.x == topLeft.y){
                        matrix[topLeft.x][topLeft.y] = ++count;
                }
               
                return matrix;
        }
       
        public static void printMatrix(int[][] matrix, int m, int n){
                for(int i = 0; i < m; i++){
                        for(int j = 0; j < n; j++){
                                System.out.format("%3d",matrix[j]);
                        }
                        System.out.println();
                }
        }


        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                int[][] matrix = null;
                int m = 9;
                int n = 9;
                matrix = spiralMatrix(m, n);
                printMatrix(matrix, m, n);
        }

}

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
不明白需求是什么,但是看得出来是直接模拟螺旋图形写的,一般螺旋是按找行数列数来写的,为什么偶数不行呢?偶数行列也有螺旋矩阵吧
算法上我也是按照模拟图形控制边界写的,数学算法太头疼了,这种应该是最直观最好理解的了,除了楼上说的对齐用\t我也没办法优化,期待神人给出好的算法{:soso_e100:}
回复 使用道具 举报
王军行 发表于 2013-4-9 20:31
不明白需求是什么,但是看得出来是直接模拟螺旋图形写的,一般螺旋是按找行数列数来写的,为什么偶数不行呢 ...

没什么需求,就是当习题练一下.偶数阵列的也可以实现.这要更改算法,而且题意没有要求.
我指的优化是指:能在效率或者其他代码简洁方面好点.至于对齐就没多少必要了.这个算法基本固定了,可以算计上上千的的螺旋阵.格式始终无法控制的.
回复 使用道具 举报
public class Circle {

int[][] numArray;
int record = 1;//记录每层的起始数字
int stepF = 0;//每层的起始下标
int stepE = 0;//每层的终止下标
int reduce = 0;//用于记录减小量

public static void main(String args[]) {

  new Circle().process();

}

public void setNum(int num) {//递归的为二维数组赋值
  if (num > 0) {//只要层数是正数继续赋值

   for (int i = stepF; i < stepE; i++) {//为每层的第一列和最后一列赋值
    numArray[i][stepF] = record;
    numArray[i][stepE - 1] = record + 3 * (num - 1) - 2 * reduce;
    reduce++;
    record++;
   }
   reduce = 1;
   for (int i = stepF + 1; i < stepE - 1; i++) {//为每层的第一行和最后一行赋值
    numArray[stepE - 1][i] = record;
    numArray[stepF][i] = record + 3 * (num - 1) - 2 * reduce;
    reduce++;
    record++;
   }
   reduce = 0;
   stepF++;
   record = record + 2 * (num - 1);//得到下一层的起始量
   stepE--;
   setNum(num - 2);//每递归一次每层边上的数字量减小2
  } else//当边数含有的数字量非正时退出递归
   return;
}

public void process() {//将数组中的数字按行列的形式输出
  String s = JOptionPane.showInputDialog("输入矩阵");
  int num = Integer.parseInt(s);
  numArray = new int[num][num];
  String space = "";
  stepE = num;
  setNum(num);
  for (int i = 0; i < num; i++) {
   for (int j = 0; j < num; j++) {
    if (numArray[i][j] < 10 && j > 0) {//保证输出是个正方形,不会因为是一位数或者2位数影响效果
     space = "  ";
    } else
     space = " ";
    System.out.print(numArray[i][j] + space);
   }
   System.out.println();//输入完一行后要换行
  }
}

}

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
黄玉昆 黑马帝 2013-4-10 08:26:54
8#
如果问题未解决,请继续追问,如果没有问题了,请将帖子分类 改为“已解决”,谢谢
回复 使用道具 举报
王瑞 中级黑马 2013-4-30 09:09:45
9#
做出来了?牛逼,我有思路但是写代码不太会,学习了!
回复 使用道具 举报
王瑞 发表于 2013-4-30 09:09
做出来了?牛逼,我有思路但是写代码不太会,学习了!

。。。。刚刚发现这是以前的帖子,哈哈~
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马