黑马程序员技术交流社区

标题: 求大神帮忙解决这个数组问题,最好能详细解答思路 [打印本页]

作者: hubby    时间: 2013-11-9 18:32
标题: 求大神帮忙解决这个数组问题,最好能详细解答思路
**螺旋填数
读入两个整数m,n,输出一个m 行n 列的矩阵,这个矩阵是1~m*n 这些自然
数按照右、下、左、上螺旋填入的结果。
例如:读入4, 5,
则输出
1 2 3 4 5
14 15 16 17 6
13 20 19 18 7
12 11 10 9 8
题目如上,我想问一下这个题该怎么着手啊?
作者: 零下五度的水    时间: 2013-11-9 19:38
从建一个二维数组着手。。。
int[][] matrix = new int[m][n];

好吧,先说一下我的大致思路,代码稍候再说
一共 m*n 个数
分 int time = (m>n) ? (2*m-1) : (2*n)  次赋值(m>n的时候是2m-1次,m<n的时候是2n次)
1. matrix[0][i]:第一行
2. matrix[i][n-1]:最后一列
3. matrix[m-1][i]:最后一行(逆序)
4. matrix[i][0]:第一列(逆序)
5. matrix[1][i]:第二行
6. matrix[i][n-2]:倒数第二列
7. matrix[m-2][i]:倒数第二行(逆序)
8. matrix[i][1]:第二列(逆序)
。。。
目测4轮是一个循环,所以外循环准备用4轮这个:for(int i=0; i<time/4; i++)
里面4个赋值循环,根据判断条件选择进入哪个循环赋值,
设一个计数器,每次赋值后+1,用以给数组元素赋值,
嗯,想起来都麻烦死了。。
作者: hurryup    时间: 2013-11-9 20:02
貌似是黑马测试题啊!
作者: hubby    时间: 2013-11-9 21:21
hurryup 发表于 2013-11-9 20:02
貌似是黑马测试题啊!

不是,是一个哥们发给我做的题,完全不知道怎么写代码。。
作者: hubby    时间: 2013-11-9 21:23
零下五度的水 发表于 2013-11-9 19:38
从建一个二维数组着手。。。
int[][] matrix = new int[m][n];

哥,你是在让我更头大么。。
作者: 零下五度的水    时间: 2013-11-9 21:26
代码送上:
   int mi = 0, ni = 0; //行起始索引,列起始索引
   int m = 8, n = 11;  //行末尾索引+1,列末尾索引+1(开始时为行数,列数)
   int elemNum = m * n; //数组总元素数
   int value = 1;  //赋值计数器
   int times = (m>n) ? (2*m-1) : (2*n);  //赋值的大循环次数(螺旋的圈数)
   int[][] matrix = new int[m][n];  //数组接收数据
   
   Flag:
   for (int i = 0; i < times/2 ; i++) {  //4次赋值循环为一个大循环(螺旋转了一圈)
    for (int a = ni; a < n; a++) {  //第一次赋值循环(第一排)
     matrix[mi][a] = value++;
     if (value > elemNum)  //如果所有元素都已经被赋值,则跳出循环,后面每个小循环都有这段代码
      break Flag;
    }
    mi++;  //数组的第一行(matrix[mi==0][x])已全部赋值,不可再被访问
    for (int a = mi; a < m; a++) {  //第二次赋值循环(最后一列)
     matrix[a][n-1] = value++;
     if (value > elemNum)
      break Flag;
    }
    n--;  //数组的最后一列(matrix[x][n-1])已全部赋值,不可再被访问
    for (int a = ni; a < n; a++) {  //第三次赋值(最后一行,逆序)
     matrix[m-1][n-a+(i-1)] = value++;  //因为n-a每轮差值会减2(n--,ni++),所以补上一个常数(i-1),以抵消差值的影响
     if (value > elemNum)
      break Flag;
    }
    m--;  //数组的最后一行(matrix[m-1][x])已全部赋值,不可再被访问
    for (int a = mi; a < m; a++) {  //第四次赋值(第一列,逆序)
     matrix[m-a+(i)][ni] = value++; //同三,因为m-a每轮差值会减2(m++,mi++),所以补上常数(i),以抵消差值的影响
     if (value > elemNum)
      break Flag;
    }
    ni++;  //数组的第一列(matrix[x][ni==0])已全部赋值,不可再被访问
   }
   for (int[] line : matrix) {  //输出语句
    for (int elem : line) {
     System.out.print(elem + "\t");
    }
    System.out.println();
   }
作者: 睡不够的猪    时间: 2013-11-9 22:19
  1. public class Two_dimensionalArrayTest {
  2. //由外向内旋转
  3.         /**
  4.          * @param args
  5.          */
  6.         public static void main(String[] args) {
  7.                
  8.                
  9.                 show(7,8);
  10.                
  11.         }
  12.        
  13.         public static void show(int m,int n)
  14.         {
  15.                 int flag = 1;
  16.                
  17.                 int[][] arr = new int[m][n];//建立一个二维数组
  18.                 //给二维数组先全部赋一个初始值,这里赋为-1(这个值不在1-m*n范围内就行)
  19.                 for(int x=0;x<m;x++)
  20.                 {
  21.                         for(int y=0;y<n;y++)
  22.                         {
  23.                                 arr[x][y]=-1;
  24.                         }
  25.                 }
  26.                 int num = 1;
  27.                 int a = 0;
  28.                 int b = 0;
  29.                 arr[a][b]=num;
  30.                 //循环给二维数组赋值
  31.                 while(num<(m*n))
  32.                 {
  33.                        
  34.                        
  35.                         if(flag==1)//定义向右走的方向,下面同理
  36.                         {
  37.                                 b++;
  38.                                 if(arr[a][b]==-1)
  39.                                         arr[a][b]=(++num);
  40.                                 //当检测到已经赋值,不再赋值,改变方向,下面同理
  41.                                 else
  42.                                 {
  43.                                         b--;
  44.                                         flag=2;
  45.                                 }
  46.                                
  47.                                 if(b+1>=n)
  48.                                 {
  49.                                         flag=2;
  50.                                 }
  51.                         }
  52.                         else if(flag==2)//向下走的方向
  53.                         {
  54.                                 a++;
  55.                                 if(arr[a][b]==-1)
  56.                                         arr[a][b]=(++num);
  57.                                 else
  58.                                 {
  59.                                         a--;
  60.                                         flag=3;
  61.                                 }
  62.                                 if(a+1>=m)
  63.                                 {       
  64.                                         flag=3;
  65.                                 }
  66.                         }
  67.                         else if(flag==3)//向左走
  68.                         {
  69.                                 b--;
  70.                                 if(arr[a][b]==-1)
  71.                                         arr[a][b]=(++num);
  72.                                 else
  73.                                 {
  74.                                         b++;
  75.                                         flag=4;
  76.                                 }
  77.                                 if(b<=0)
  78.                                 {
  79.                                        
  80.                                         flag=4;
  81.                                 }
  82.                         }
  83.                         else if(flag==4)//向上走
  84.                         {
  85.                                 a--;
  86.                                 if(arr[a][b]==-1)
  87.                                         arr[a][b]=(++num);
  88.                                 else
  89.                                 {
  90.                                         a++;
  91.                                         flag=1;
  92.                                 }
  93.                                 if(a<=0)
  94.                                 {
  95.                                         flag=1;
  96.                                 }
  97.                         }
  98.                 }
  99.                 //最后打印出二维数组的值即可
  100.                 for(int x=0;x<m;x++)
  101.                 {
  102.                         for(int y=0;y<n;y++)
  103.                         {
  104.                                 System.out.print(arr[x][y]+"\t");
  105.                         }
  106.                         System.out.println();
  107.                 }
  108.         }

  109. }
复制代码

作者: hubby    时间: 2013-11-10 09:13
零下五度的水 发表于 2013-11-9 21:26
代码送上:
   int mi = 0, ni = 0; //行起始索引,列起始索引
   int m = 8, n = 11;  //行末尾索引+1,列 ...

谢谢大神  我会好好研究你的代码的
作者: hubby    时间: 2013-11-10 09:29
零下五度的水 发表于 2013-11-9 21:26
代码送上:
   int mi = 0, ni = 0; //行起始索引,列起始索引
   int m = 8, n = 11;  //行末尾索引+1,列 ...

大神,那个大螺旋的次数为什么是(2m-1)/2或者是(2n)/2?这个规律是怎么来的能详细说一下么?
作者: 零下五度的水    时间: 2013-11-10 12:59
因为是从第一行开始赋值,赋值顺序是行-列-行-列。。。
行大于列的时候,最后赋值的是行所以是2m-1

P.S.楼下那位的思路比我的好
作者: hubby    时间: 2013-11-10 20:03
睡不够的猪 发表于 2013-11-9 22:19

多谢大哥的代码!我已经大概其知道了!谢啦!!!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2