黑马程序员技术交流社区

标题: 输出 n=5 的螺旋方阵 [打印本页]

作者: heimaheima123    时间: 2014-12-13 21:05
标题: 输出 n=5 的螺旋方阵
输出 n=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
求大神指教

作者: c91764000    时间: 2014-12-13 21:11
同问~坐等大神来呀:Q
作者: 被风扬起的沙    时间: 2014-12-13 21:16
一块坐等,伤不起啊
作者: run_wind    时间: 2014-12-13 21:28
干想可不行,这种题你拿一只笔,在纸上画一下,在写个二维数组,找规律
  1. package com.gotoheima;

  2. /**
  3. *
  4. * 写一方法,打印等长的二维数组,要求从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列。 如: n = 4 则打印:
  5. * 1        2        3        4
  6. * 12        13        14        5
  7. * 11        16        15        6
  8. * 10        9        8        7
  9. *
  10. */
  11. public class Test18
  12. {
  13.         public static void main(String[] args)
  14.         {
  15.                 printMath(60);
  16.         }
  17.        
  18.         public static void printMath(int n)
  19.         {
  20.                 int[][] arr = new int[n][n];
  21.                 int x = 0;
  22.                 int y = 0;
  23.                 int max = arr.length-1;
  24.                 int min = 0;
  25.                 int num = 1;
  26.                
  27.                 while (min<=max)
  28.                 {
  29.                         //right
  30.                         while (y<max)
  31.                         {
  32.                                 arr[x][y++] = num++;
  33.                         }
  34.                         //down
  35.                         while (x<max)
  36.                         {
  37.                                 arr[x++][y] = num++;
  38.                         }
  39.                         //left
  40.                         while (y>min)
  41.                         {
  42.                                 arr[x][y--] = num++;
  43.                         }
  44.                         //up
  45.                         while (x>min)
  46.                         {
  47.                                 arr[x--][y] = num++;
  48.                         }
  49.                         //如果是奇数,可能赋值不上
  50.                         if (min == max)
  51.                         {
  52.                                 arr[x][y] = num;
  53.                         }
  54.                        
  55.                         max--;
  56.                         min++;
  57.                        
  58.                         x++;
  59.                         y++;
  60.                 }
  61.                
  62.                 for (int i=0;i<arr.length;i++)
  63.                 {
  64.                         for (int j=0;j<arr.length;j++)
  65.                         {
  66.                                 System.out.print(arr[i][j]+"\t");
  67.                         }
  68.                         System.out.println();
  69.                 }
  70.         }
  71. }
复制代码

作者: as604049322    时间: 2014-12-13 21:32
run_wind 发表于 2014-12-13 21:28
干想可不行,这种题你拿一只笔,在纸上画一下,在写个二维数组,找规律
...

你的思路想不错,赞一个,能写点注释就更好了~
作者: 18334705181    时间: 2014-12-13 21:36
run_wind 发表于 2014-12-13 21:28
干想可不行,这种题你拿一只笔,在纸上画一下,在写个二维数组,找规律
...

不用数组可以么?求大黑马指教
作者: 18334705181    时间: 2014-12-13 21:37
run_wind 发表于 2014-12-13 21:28
干想可不行,这种题你拿一只笔,在纸上画一下,在写个二维数组,找规律
...

不用数组可以么?求指教
作者: Honelyboy    时间: 2014-12-13 21:44
大神,不错。赞一个。
作者: 侯鹏成    时间: 2014-12-13 21:47
大神用数组做的,我等小虾米还没学到那程度,慢慢来
作者: heimaheima123    时间: 2014-12-13 21:49
me  too  ,me too
作者: 清浅。。    时间: 2014-12-13 21:51
大神,树上说不可以用数组,要用嵌套或者之前的知识去做,求大神解答啊~
作者: heimaheima123    时间: 2014-12-13 21:51
run_wind 发表于 2014-12-13 21:28
干想可不行,这种题你拿一只笔,在纸上画一下,在写个二维数组,找规律
...

大神啊,太赞了,加上注释就完美了
作者: Dr.Sparta    时间: 2014-12-13 21:54
自己感觉建立转向标示比较容易不过也可以用递归
public class Demo{
        private int[,] _SpiralMatrix;
        private int _N;

        public SpiralMatrix(int n)
        {
            _SpiralMatrix = new int[n, n];
            _N = n;
        }
        /// <summary>
        /// 递归算法
        /// </summary>
        /// <param name="start">start:矩阵开始的位置,如为0表示矩阵[0,0]元素</param>
        /// <param name="num">矩阵的维数</param>
        /// <param name="begin">起始数字</param>
        public void Computer(int start,int num,int begin)
        {
            if (start == num)//输入为偶数时
            {
                return;
            }
            else if (start == num - 1)//输入为奇数时
            {
                _SpiralMatrix[start, num - 1] = begin;
                return;               
            }
            else
            {
                for (int i = start; i < num; i++)
                {
                    _SpiralMatrix[start,i] = begin;
                    begin++;
                }
                for (int j = start + 1; j < num; j++)
                {
                    _SpiralMatrix[j, num - 1] = begin;
                    begin++;
                }
                for (int k = num - 2; k >= start; k--)
                {
                    _SpiralMatrix[num-1, k] = begin;
                    begin++;
                }
                for (int l = num - 2; l >= start+1; l--)
                {
                    _SpiralMatrix[l, start] = begin;
                    begin++;
                }
                Computer(start + 1, num - 1, begin);
            }
        }

        /// <summary>
        /// 字符串化,方便对象输出
        /// </summary>
        /// <returns>字符串后的矩阵</returns>
        public string ToString()
        {
            string temp="";
            for(int i=0;i<_N;i++)
            {
                for(int j=0;j<_N;j++)
                {
                    temp+=_SpiralMatrix[i,j]+" ";
                }
                temp+="\r\n";
            }
            return temp;
        }
   
作者: 董晗    时间: 2014-12-13 22:03
看不懂。。。前面基础不好
作者: 不淡定,小学生    时间: 2014-12-13 23:21
好吧,你们这个我不懂,但是我也想知道,不用数组能不能做。脑细胞各种死。
作者: 清浅。。    时间: 2014-12-13 23:57
run_wind 发表于 2014-12-13 21:28
干想可不行,这种题你拿一只笔,在纸上画一下,在写个二维数组,找规律
...

你这不加注释看起来还真是费劲啊!!!
作者: 冥夜    时间: 2014-12-14 00:00
  1. public static void main(String[] args)
  2.         {
  3.                 printLuoxuan(6);
  4.         }

  5.         private static void printLuoxuan(int i)
  6.         {
  7.                 //整体思路,既然是螺旋矩阵就螺旋赋值,num为保存的数字。首先观察到赋值是向右,向下,向左,向上进行赋值,然后每次都重复这个过程直到全部赋值完毕。
  8.                 //每完成一次循环都会使坐标值变化1.所以用count表示圈数来进行赋值
  9.                 int[][] arr=new int[i][i];
  10.                 int num=1;//赋值的数字
  11.             int count=0;//圈数
  12.                 while(num<(i*i+1))//i阶螺旋矩阵总共i*i个数
  13.                 {
  14.                         for(int j=count;j<i-count;j++)//从最左上开始赋值,向右赋值。第一圈纵坐标是0,第二是1.。。
  15.                                 arr[j][count]=num++;
  16.                        
  17.                         for(int j=count+1;j<i-count;j++)//向下赋值,第一圈横坐标是i-1,第二圈是i-2..。
  18.                                 arr[i-count-1][j]=num++;
  19.                                
  20.                         for(int j=i-count-2;j>count-1;j--)//向左赋值,第一圈纵坐标是i-1,第二圈是i-2。。。
  21.                                 arr[j][i-count-1]=num++;
  22.                        
  23.                         for(int j=i-count-2;j>count;j--)//向上赋值,第一圈横坐标是0,第二圈是1.。。
  24.                                 arr[count][j]=num++;
  25.                         count++;//走完一圈圈数+1
  26.                 }
  27.                
  28.                 for(int y=0;y<i;y++)
  29.                 {
  30.                         for(int x=0;x<i;x++)
  31.                         {
  32.                                 System.out.print(arr[x][y]+"\t");
  33.                         }
  34.                         System.out.println();
  35.                 }
  36.         }
复制代码

作者: 烟默year    时间: 2014-12-14 00:33
heimaheima123 发表于 2014-12-13 21:51
大神啊,太赞了,加上注释就完美了

这个帖子不水!够给力
作者: 0_TNT_0    时间: 2014-12-14 01:20
还没学数组。。。。。
作者: Eagle    时间: 2014-12-14 03:00
冥夜 发表于 2014-12-14 00:00

搞得不错,嘿嘿。思路杠杠滴,学习你的思路又自己思考,终于还是自己做出来了
作者: Eagle    时间: 2014-12-14 03:01
本帖最后由 Eagle 于 2014-12-14 03:27 编辑

刚完成,献上成果,有可能有错误的地方,大家多指正指正啊。
  1. <div class="blockcode"><blockquote>/*
  2. 需求:打印螺旋数字。6列6排的.x列x排的
  3. 效果如下:
  4. 一排6个的
  5. 1       2       3       4       5       6
  6. 20      21      22      23      24      7
  7. 19      32      33      34      25      8
  8. 18      31      36      35      26      9
  9. 17      30      29      28      27      10
  10. 16      15      14      13      12      11

  11. 一排9个的
  12. 1       2       3       4       5       6       7       8       9
  13. 32      33      34      35      36      37      38      39      10
  14. 31      56      57      58      59      60      61      40      11
  15. 30      55      72      73      74      75      62      41      12
  16. 29      54      71      80      81      76      63      42      13
  17. 28      53      70      79      78      77      64      43      14
  18. 27      52      69      68      67      66      65      44      15
  19. 26      51      50      49      48      47      46      45      16
  20. 25      24      23      22      21      20      19      18      17

  21. 个人思路:定义二维数组,进行循环赋值。

  22. 循环里面嵌套循环,定义四个内循环,分别控制向右赋值、向下赋值、向左赋值、向上赋值。

  23. 定义一个变量num,作为将要赋值的数。每赋值一次,自增一次。
  24. 在外循环的内循环里。
  25. 向右赋值的循环第一次循环x次,第二次循环x-1次,第三次循环x-2次,向下、向左、向上的都是一样。
  26. 怎么判断是否还要不要循环呢?通过赋值的数num判断,因为x的平方就是最后的值 。所以只要判断num是否等于x的平方+1就好。

  27. 需要定义一个变量count,来控制内循环的循环次数。

  28. 原理:
  29. arr[i][j]   =    arr[3][3]

  30. arr[0][0]、arr[0][1]、arr[0][2]
  31. arr[1][0]、arr[1][1]、arr[1][2]
  32. arr[2][0]、arr[2][1]、arr[2][2]

  33. 第一步先控制向右就是i的值不变,j的值递增。
  34.                 第二次是i的值增加了1。j的范围缩小了2.
  35. 第二步控制向下,j的值没有变,i的值递增。
  36.                 注意转角处,赋值时i应该从1开始。第二次j的值减去1。i的值小了2.
  37. 都三步控制向左赋值,i的值没有变,j的值递减。
  38.                 注意转角。第二次i的值减一。j的值少了2.
  39. 第四步,控制向上递增,j的值没有变,i的值递减。
  40.                 第二次j的值加了1,i的值少了2.



  41. */
  42. class LuoXuanDemo
  43. {
  44.     public static void main(String[] args){
  45.         printLuoXuan(9);
  46.                
  47.     }

  48.         public static void printLuoXuan(int x){
  49.                 int num=1;//将要赋值的数
  50.                 int count =0;//控制内循环的循环次数。
  51.                 int[][] arr = new int[x][x];
  52.                 int max = x*x+1;//判断num的最大值,因为在循环里修改了x的值,所以先记录下来。
  53.                 while (num < max)
  54.                 {
  55.                         //控制向右赋值,
  56.                         for(int a=count;a<x ; a++){
  57.                                 arr[count][a] = num++;//第一次arr[0][0-5]/第二次arr[1][1-4]
  58.                         }
  59.                         //控制向下赋值
  60.                         for(int a=count+1;a<x ; a++){//这里的count+1原理也是和下面一样。第一次转角的地方
  61.                                 arr[a][x-1] = num++;//第一次arr[0-5][5]/第二次arr[1-4][4]
  62.                         }
  63.                         //控制向左赋值
  64.                         for(int a=x-2;a>=count ; a--){//这里a为什么要x减2呢?因为如果是x-1,则会赋值到转角的地方。这样就重复赋值了。
  65.                                 arr[x-1][a] = num++;//第一次arr[5][5-0]/第二次arr[4][4-1]
  66.                         }
  67.                         //控制向上赋值
  68.                         for(int a=x-2;a>count ; a--){//x-2原理同上
  69.                                 arr[a][count] = num++;//第一次arr[5-0][0]/第二次arr[4-1][1]
  70.                         }
  71.                         x--;
  72.                         count++;
  73.                 }
  74.                 //遍历数组
  75.                 for (int a=0;a<arr.length ;a++)
  76.                 {
  77.                         for (int b=0;b<arr[a].length ;b++ )
  78.                         {
  79.                                 System.out.print(arr[a][b]+"\t");
  80.                         }
  81.                         System.out.println();
  82.                        
  83.                 }

  84.         }
  85. }
复制代码



作者: dandan520    时间: 2014-12-14 08:11
我只学了输出语句,可以用输出语句嘛?
作者: Jennifer    时间: 2014-12-14 09:04
除了数组想不到其他,看了楼上大神的代码与注释,加上自己的理解,懂了不少,谢谢楼上各位的分享
作者: Jason996    时间: 2014-12-14 09:34
不用数组可以写出来嘛
作者: heimaheima123    时间: 2014-12-21 00:45
Dr.Sparta 发表于 2014-12-13 21:54
自己感觉建立转向标示比较容易不过也可以用递归
public class Demo{
        private int[,] _SpiralMatrix ...

好详细啊,谢谢
作者: heimaheima123    时间: 2014-12-21 00:46
Dr.Sparta 发表于 2014-12-13 21:54
自己感觉建立转向标示比较容易不过也可以用递归
public class Demo{
        private int[,] _SpiralMatrix ...

谢谢,解释的好详细啊
作者: 只会金克斯    时间: 2014-12-21 14:34
有了代码 ,还是看不懂 怎么办
作者: zmhlnrs    时间: 2014-12-21 15:57
import java.util.Scanner;
class ArreyTest
{
        public static void main(String[] args)
        {
                System.out.print("请输入列数:");
                Scanner sc = new Scanner(System.in);

                int x=0,y,z;
                //一维数组中元素的个数
                int k=sc.nextInt();
                int count=1;
                System.out.print("请输入行数:");
                //二维数组的元素个数
                int num = sc.nextInt();
                int zi=(num+1)/2;
                int[][] arr = new int [num][k];
                for ( z=0;z<zi ;z++ )
                {
                        for ( y=z;y<k-1; y++)
                        {
                                arr[z][y]=count++;
                        }
                        for ( x=z;x<num-1;x++ )
                        {
                                arr[x][y]=count++;       
                        }
                        for (y=k-1;y>z;y-- )
                        {
                                arr[x][y]=count++;       
                        }
                        for (x=num-1;x>z;x-- )
                        {
                                arr[x][y]=count++;
                        }
                        num--;
                        k--;
                }
                for (int a=0;a<arr.length; a++)
                {
                        for (int b=0;b<arr[a].length ;b++ )
                        {
                                System.out.print(arr[a][b]+"\t");
                        }
                        System.out.println();
                }
        }
}
写了一个用二维数组做的  大神帮看下哪里可以改进
作者: woaixuexi    时间: 2014-12-21 16:02
冥夜 发表于 2014-12-14 00:00

学到东西了,谢谢:)
作者: 银离子    时间: 2014-12-21 21:56
  1. import java.io.*;
  2. public class copydemo {

  3.         /**
  4.          * @param args
  5.          */
  6.         public static void main(String[] args)throws IOException
  7.         {
  8.                 // TODO Auto-generated method stub
  9.                 BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
  10.                
  11.                 while(true)
  12.                 {        String str=br.readLine();
  13.                         int n=Integer.parseInt(str);
  14.                                        
  15.                         if(n<=1){
  16.                                 break;
  17.                         }
  18.                         int[][] arr=new int[n][n];
  19.                         int temp=1;
  20.                         int count=0;
  21.                
  22.                         for(int yi=count,er=n-1;yi<=er;yi++,er--)
  23.                                 {       
  24.                                         for(int h=yi,l=er,a=0,z=yi;a<(er-yi);z++,temp++,a++)
  25.                                                 {
  26.                                                         arr[h][z]=temp;
  27.                                                         arr[z][l]=temp+er-yi;
  28.                                                         arr[n-h-1][n-z-1]=temp+2*(er-yi);
  29.                                                         arr[n-z-1][h]=temp+3*(er-yi);
  30.                                                        
  31.                                                 }
  32.                                                 temp=arr[yi+1][yi]+1;
  33.                                                
  34.                                                 count++;
  35.                                 }
  36.                         if(n%2==1)
  37.                                 arr[(n-1)/2][(n-1)/2]=n*n;
  38.                        
  39.                         for(int a=0;a<n;a++){
  40.                                 for(int b=0;b<n;b++){
  41.                                         System.out.print(arr[a][b]+"\t");
  42.                                         }
  43.                                 System.out.println();
  44.                                 System.out.println();
  45.                         }
  46.                        
  47.                        
  48.                
  49.                 }
  50.                
  51.                 br.close();
  52.         }
  53.        
  54. }
复制代码

作者: 后悔药    时间: 2014-12-21 22:42
今天下载的测试题,晚上刚做到这一题,把我的思路拿出来给大家共享一下,我的思路很简单,注释太臃肿了。希望能拿点技术分
  1. public class Test {

  2.         public static void main(String[] args) {
  3.                
  4.                 Scanner input = new Scanner(System.in);
  5.                 System.out.println("请输入一个整数: ");
  6.                 //接收一个整数
  7.                 int n = input.nextInt();

  8.                 int[][] out = test(n);

  9.                 for (int i = 0; i < n; i++) {
  10.                         for (int j = 0; j < n; j++) {
  11.                                 System.out.print(out[i][j] + "\t");
  12.                         }
  13.                         System.out.print("\r\n");
  14.                 }

  15.                 input.close();
  16.         }

  17.         /**
  18.          * 总思路:通过标签flag轮流给二维数组右上角和左下角的两边进行赋值,每次循环只赋值半圈
  19.          * @param n
  20.          * @return
  21.          */
  22.         static int[][] test(int n) {
  23.                 int[][] out = new int[n][n];

  24.                 // 定义第一个数
  25.                 int num = 1;

  26.                 // 每次画的行和列的数据的个数
  27.                 int m = n;

  28.                 // 每次要打印的行和列
  29.                 int a = 0, b = -1;
  30.                 /**
  31.                  * flag为true就给右上角两边赋值
  32.                  * flag为false就给左下角两边赋值
  33.                  * */
  34.                 boolean flag = true;
  35.                
  36.                 //结束的标记是行和列上的数据个数为0
  37.                 while (m != 0) {
  38.                         for (int i = 0; i < m; i++) {
  39.                                 if (flag) {
  40.                                         //向右赋值
  41.                                         out[a][++b] = num++;
  42.                                 } else {
  43.                                         //向左赋值
  44.                                         out[a][--b] = num++;
  45.                                 }
  46.                         }

  47.                         for (int i = 0; i < m - 1; i++) {
  48.                                 if (flag) {
  49.                                         //向上赋值
  50.                                         out[++a][b] = num++;
  51.                                 } else {
  52.                                         //向下赋值
  53.                                         out[--a][b] = num++;
  54.                                 }
  55.                         }
  56.                         //每画完半圈下一次行数和列数上要画的数据数个数减1
  57.                         m--;
  58.                         //翻转标签
  59.                         flag = !flag;
  60.                 }
  61.                 return out;
  62.         }
  63. }
复制代码

作者: zcyemenye    时间: 2014-12-21 22:44
看各路大神:lol
作者: 球球_    时间: 2015-9-1 02:24
解释的很详细,一下子就懂了,谢谢大神
作者: wuming668    时间: 2015-9-20 08:50
好有难度的一个帖子.
作者: duanbozhi    时间: 2016-4-14 18:27
都是大神啊.





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