黑马程序员技术交流社区

标题: 为什么我的螺旋方阵打印不出奇数的时候中心那个数 [打印本页]

作者: 随缘就好    时间: 2015-4-7 21:17
标题: 为什么我的螺旋方阵打印不出奇数的时候中心那个数
  1. /*
  2.         第四题:
  3.         输出 n=5 的螺旋方阵
  4.         1  2  3  4  5
  5.         16 17 18 19 6
  6.         15 24 25 20 7
  7.         14 23 22 21 8
  8.         13 12 11 10 9
  9.        
  10.         思路:
  11.                 打印这一组数首先想到的是一行一行打印,但是很麻烦
  12.                 然后我们可以考虑到用二维数组吧数字装起来打印
  13.                 arr{{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}}
  14.                 这样就是基本上解决这个问题了,数据存入有很多方法
  15.                 我使用的是固定角标 一层一层向内输出
  16.                 但是我的方法有一个弊端奇数时中心的最后打印不出
  17. */
  18. import java.util.Scanner;
  19. class Day04_04
  20. {
  21.         public static void main(String[] args){
  22.                 Scanner s = new Scanner (System.in);
  23.                 while(true){
  24.                         System.out.println("请输入一个正整数:");
  25.                         int x = s.nextInt();
  26.                         Alg(x);       
  27.                 }

  28.         }
  29.         public static void Alg(int n){
  30.                 int arr[][]=new int[n][n];                        //定义一个数组用于储存
  31.                 for (int x=0,y=0,i=1,kx=0,ky=0;i<n*n;kx++,ky++){        //x,y分别用于做二维数组 的X,变量和y变量,i为当前二位数组的值,
  32.                                                                                                                         //kx,ky分别代表着x的增量和y的增量,作用为循环向内移动一层
  33.                         //这里是数据从左往右移动,X不变Y变,kx和ky在此处分别给x,y赋值
  34.                         //表示数组角标向内一层,y<n-1-ky,是把y的可循环的值向内减一
  35.                         //该循环打印的值是  1、2、3、4 ,17、18
  36.                         for (x=kx,y=ky;y<n-1-ky;y++,i++){
  37.                                 arr[x][y]=i;//x=0;y=4
  38.                         }
  39.                         //这里是数据从上往下移动,Y不变X变,x,y刚好可以沿用上一次的值
  40.                         //表示数组角标向内一层,x<n-1-ky,是把x的可循环的值向内减一
  41.                         //该循环打印的值是5、6、7、8, 19、20                       
  42.                         for (;x<n-1-kx;x++,i++){
  43.                                 arr[x][y]=i;//x=4;y=4
  44.                         }
  45.                         //这里是数据从右往左移动,X不变Y变,x,y刚好可以沿用上一次的值
  46.                         //表示数组角标向内一层,y>0+ky,是把y的可循环的值向内减一
  47.                         //该循环打印的值是 9\1\0\11\12,21\22
  48.                         for (;y>0+ky;y--,i++){
  49.                                 arr[x][y]=i;//x=4;y=0
  50.                         }
  51.                         //这里是数据从下往上移动,Y不变X变,x,y刚好可以沿用上一次的值
  52.                         //表示数组角标向内一层,x>0+kx,是把x的可循环的值向内减一
  53.                         //打印的值分别是13\14\15\16,23,24       
  54.                         for (;x>0+kx;x--,i++){
  55.                                 arr[x][y]=i;//y=0;x=0
  56.                         }
  57.                        
  58.                 }       
  59.                 //然后我们会发现当我们输入奇数的时候最后一个值打印不出求各位大神打救
  60.                 //这个就是把最后一个值打印出来的判断
  61.                 if(n%2!=0){
  62.                         int m=(n-1)/2;
  63.                         arr[m][m]=n*n;
  64.                 }
  65.         //        遍历数组,打印
  66.                 for (int i=0;i<n ;i++ )
  67.                 {
  68.                         for (int j=0;j<n ;j++ )
  69.                         {
  70.                                 System.out.print(arr[i][j]+"\t");
  71.                         }
  72.                         System.out.println();
  73.                 }
  74.         }
  75. }
复制代码



作者: 倒骑驴走着瞧    时间: 2015-4-7 21:19
不错,转转就转晕了,注释写的很好
作者: tu3    时间: 2015-4-7 21:21
作为还在hello world混的,
我表示我看不明白
作者: awsyc    时间: 2015-4-7 21:21
必须赞一个,我头都转晕了我,都没看出来!
作者: 18234133910    时间: 2015-4-7 21:22
果然代码还是自己写的才看的清楚··
作者: CZTTZ    时间: 2015-4-7 21:23
还是有点没看明白
作者: caotierong    时间: 2015-4-7 21:25
转晕了,不过注释写的很好!
作者: 随缘就好    时间: 2015-4-7 21:26
求给位帮我看看啊,我中间那个用了if强行打印的,但是应该可以全部用for打印的啊
作者: 东东西西    时间: 2015-4-7 21:35
转成螺丝了  不明白
作者: Mr.Kaizhei    时间: 2015-4-7 21:38
好厉害啊!!!!!!!
作者: Mr.Kaizhei    时间: 2015-4-7 21:39
tu3 发表于 2015-4-7 21:21
作为还在hello world混的,
我表示我看不明白

你的黑马币-4是怎么做到的????
作者: dxf578939729    时间: 2015-4-7 21:53
i=1;i<n*n....这才到24吧。。。加个等于号应该就可以了吧
作者: lingda21    时间: 2015-4-7 21:54
大神都,表示菜鸟还看不明白
作者: 随缘就好    时间: 2015-4-7 21:54
dxf578939729 发表于 2015-4-7 21:53
i=1;i

加个等号整个程序就疯掉了,因为25的时候没有满足的for然后就无线循环了
作者: deziko    时间: 2015-4-7 22:32
太赞了!!!!!!
作者: 呐拽    时间: 2015-4-7 22:42
表示这个看不懂
作者: fantacyleo    时间: 2015-4-7 22:42
同样基于按层填充思路,递归版本。按层填充,应该都是要考虑奇偶差别的
  1. public class Tests {

  2.         public static void main(String[] args) {
  3.                 int[][] a = new int[8][8];
  4.                 fill(a, 0, 1);
  5. //                fill1(a);
  6.                 printSquare(a);
  7.                
  8.         }
  9.         
  10.         public static void fill(int[][] square, int layer, int num) {
  11.                 int len = square.length - layer * 2;
  12.                 if (len == 0)
  13.                         return;
  14.                 if (len == 1) {
  15.                         square[layer][layer] = num;
  16.                         return;
  17.                 }
  18.                 int row = layer, col = layer;
  19.                 for (;col < square.length - layer; col++)
  20.                         square[row][col] = num++;
  21.                
  22.                 for (col--, row++;row < square.length - layer; row++)
  23.                         square[row][col] = num++;
  24.                 for (row--, col--;col >= layer; col--)
  25.                         square[row][col] = num++;
  26.                 for (col++, row--; row > layer; row--)
  27.                         square[row][col] = num++;
  28.                 fill(square, layer+1, num);
  29.         }
  30. }
复制代码

作者: taany    时间: 2015-4-7 22:42
大神的世界我们永远不懂,还是继续去敲hello world
作者: 随缘就好    时间: 2015-4-7 23:07
fantacyleo 发表于 2015-4-7 22:42
同样基于按层填充思路,递归版本。按层填充,应该都是要考虑奇偶差别的
...

额  大哥你这个好像和我那个好像,但是也是一种的方式;但是没有解决我的问题啊{:3_62:}
作者: fantacyleo    时间: 2015-4-7 23:13
随缘就好 发表于 2015-4-7 23:07
额  大哥你这个好像和我那个好像,但是也是一种的方式;但是没有解决我的问题啊 ...

已经告诉你了嘛:同样基于按层填充思路。当然看着像。不过我刚才试了一下,我这个代码实际上已经解决了奇偶判断问题:
  1. public static void fill(int[][] square, int layer, int num) {
  2.                 int start = square.length - layer * 2;
  3.                 if (start <= 0)
  4.                         return;
  5.        
  6.                 int row = layer, col = layer;
  7.                 for (;col < square.length - layer; col++)
  8.                         square[row][col] = num++;
  9.                
  10.                 for (col--, row++;row < square.length - layer; row++)
  11.                         square[row][col] = num++;
  12.                 for (row--, col--;col >= layer; col--)
  13.                         square[row][col] = num++;
  14.                 for (col++, row--; row > layer; row--)
  15.                         square[row][col] = num++;
  16.                 fill(square, layer+1, num);
  17.           
  18.          
  19.         }
复制代码

作者: 一米一光年    时间: 2015-4-7 23:16
必须赞一个,我头都转晕了我,都没看出来!
作者: 随缘就好    时间: 2015-4-7 23:21
fantacyleo 发表于 2015-4-7 23:13
已经告诉你了嘛:同样基于按层填充思路。当然看着像。不过我刚才试了一下,我这个代码实际上已经解决了奇 ...

我在看看哈{:3_65:}
作者: fantacyleo    时间: 2015-4-7 23:30
随缘就好 发表于 2015-4-7 23:21
我在看看哈

我明白你的问题在哪儿了。我们的代码区别在于,转角处的位置交给谁来填。你的做法是,把转角位置作为新方向的起点。我的做法是,转角的下一个位置作为新方向的起点。那么当遇到奇数时,最内层只有1个数,这个数实际上是扮演了4个转角的角色。当向右填充时,它是右和下方向的转角,右是不填充它的。当向下填充时,它是下和左方向的转角,下是不填充它的。以此类推就是所有方向都不填充它,最后就空着没人填了
作者: Sylvanas    时间: 2015-4-8 00:15
可能是迭代的时候漏了最后一个
作者: 随缘就好    时间: 2015-4-8 06:32
fantacyleo 发表于 2015-4-7 23:30
我明白你的问题在哪儿了。我们的代码区别在于,转角处的位置交给谁来填。你的做法是,把转角位置作为新方 ...

哦   ,谢谢大哥,终于找出问题了{:3_64:}
作者: 俊勇    时间: 2015-4-8 22:24
这个比较全面,厉害~~
作者: 风飘逸    时间: 2015-4-8 22:26
看不懂啊,待会好好想想
作者: 涿郡丶二哥    时间: 2015-4-8 22:31
你是不是蚊子红?
作者: 随缘就好    时间: 2015-4-8 23:36
涿郡丶二哥 发表于 2015-4-8 22:31
你是不是蚊子红?

不是{:3_53:}
作者: 胡帅    时间: 2015-4-8 23:59
  1. /*
  2. 输出 n=5 的螺旋方阵
  3.         1  2  3  4  5
  4.         16 17 18 19 6
  5.         15 24 25 20 7
  6.         14 23 22 21 8
  7.         13 12 11 10 9

  8. */
  9. class  Example001
  10. {
  11.         public static void main(String[] args)
  12.         {
  13.                        
  14.                 int size = 5;
  15.                 int arr[][] = new int[size][size];
  16.                 int i, j, k = 0, n, m;
  17.                 n = size;
  18.                 for (i = 0; i < n; i++) {
  19.                         // 顶边,从左到右,行不变列变
  20.                         for (j = i; j <= n - i - 1; j++)
  21.                                 arr[i][j] = ++k;// i=0进来是输出1、2、3、4、5; i=1进来输出17、18、19 ;i=3,输出25
  22.                        
  23.                         // 右边,从上到下,行变列不变
  24.                         for (j = i + 1; j <= n - i - 1; j++)
  25.                                 arr[j][n - i - 1] = ++k; // i=0进来是输出6、7、8、9 ; i=1进来输出20、21
  26.                        
  27.                         // 底边,从右到左,行不变列变
  28.                         for (j = n - i - 2; j >= i; j--)
  29.                                 arr[n - i - 1][j] = ++k; // i=0进来是输出10、11、12、13;i=1进来输出22、23
  30.                        
  31.                         // 左边,从下到上,行变列不变
  32.                         for (j = n - i - 2; j >= i + 1; j--)
  33.                                 arr[j][i] = ++k; // i=0进来是输出14、15、16 ;i=1进来输出24
  34.                 }
  35.                
  36.                 for (i = 0; i < n; i++) {
  37.                         for (j = 0; j < n; j++)
  38.                                 System.out.print(arr[i][j] + "\t");
  39.                         System.out.println();
  40.                 }
  41.                
  42.                
  43.                
  44.         }
  45. }
复制代码

作者: 梦想着    时间: 2015-4-9 10:43
晕了   我还是复制下来运行一下看看
作者: lurenge    时间: 2015-4-9 11:31
这个问题其实 我都没看懂,楼主的分析 让我理解了 赞一个
作者: 君嘘    时间: 2015-4-9 14:42
打印不出来是因为最后的数没有存进数组吧……
因为用i<n*n的话  n为奇数时就无法判断最后一次从左到右的for循环

解决方法很简单  如果n为奇数   手动把n*n的值传入数组的中心角标   arr [n/2][n/2]




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