黑马程序员技术交流社区

标题: 入学测试题 [打印本页]

作者: 不系之舟王    时间: 2014-12-30 09:49
标题: 入学测试题
一道入学测试题,写一方法,打印等长的二维数组,要求从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列。 如: 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
实在想不出来怎么做,看看别人的代码,有一个地方不懂。不懂的地方在代码注释上,希望各位大师给解答一下

  1. public class java {
  2.         public static void main(String[] args) {  
  3.         //调用打印从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列的二维数组方法  
  4.         arrPrint(5);  
  5.     }  
  6.     //打印从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列的二维数组  
  7.     public static void arrPrint(int num){  
  8.         //定义定长二维数组  
  9.         int[][] arr = new int[num][num];  
  10.         int n = arr.length;  
  11.         int count = 0;  
  12.         int max = 0;  
  13.         //递归为二维数组赋值  
  14.         rec2DArr(arr,n,count,max);  
  15.         //打印  
  16.         print2DArr(arr);  
  17.     }  
  18.     public static void rec2DArr(int[][] arr,int n,int count,int max){  
  19.         //递归控制条件  
  20.         if(n>0){  
  21.             //纵坐标控制值  
  22.             int k = 0;  
  23.             //(n-1)*4代表每一圈的数值范围  
  24.             for(int i=0;i<(n-1)*4;i++){  
  25.                 //在上边赋值  
  26.                 if(i<n-1){  
  27.                     arr[count+0][count+i] = ++max;  
  28.                 }  
  29.                 //向右边赋值  
  30.                 else if(i<2*n-2){  
  31.                     arr[count+k++][arr.length-1-count]=++max;  
  32.                 }  
  33.                 //在下边赋值   
  34.                 else if(i<3*n-3){     <font color="#ff0000">//当n=8时,数组是arr[5-1-0][3+0]??????实际应该是arr[3][4]啊,对于8这个临界值,就应该在这个if语句中啊?????</font>
复制代码





作者: 不系之舟王    时间: 2014-12-30 09:53
好吧,没怎么在论坛发过贴,格式怎么又错了,代码少了,完整代码
  1. public class java {
  2.         public static void main(String[] args) {  
  3.         //调用打印从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列的二维数组方法  
  4.         arrPrint(5);  
  5.     }  
  6.     //打印从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列的二维数组  
  7.     public static void arrPrint(int num){  
  8.         //定义定长二维数组  
  9.         int[][] arr = new int[num][num];  
  10.         int n = arr.length;  
  11.         int count = 0;  
  12.         int max = 0;  
  13.         //递归为二维数组赋值  
  14.         rec2DArr(arr,n,count,max);  
  15.         //打印  
  16.         print2DArr(arr);  
  17.     }  
  18.     public static void rec2DArr(int[][] arr,int n,int count,int max){  
  19.         //递归控制条件  
  20.         if(n>0){  
  21.             //纵坐标控制值  
  22.             int k = 0;  
  23.             //(n-1)*4代表每一圈的数值范围  
  24.             for(int i=0;i<(n-1)*4;i++){  
  25.                 //在上边赋值  
  26.                 if(i<n-1){  
  27.                     arr[count+0][count+i] = ++max;  
  28.                 }  
  29.                 //向右边赋值  
  30.                 else if(i<2*n-2){  
  31.                     arr[count+k++][arr.length-1-count]=++max;  
  32.                 }  
  33.                 //在下边赋值  
  34.                 else if(i<3*n-3){  
  35.                     arr[arr.length-1-count][(k--)+count]=++max;  
  36.                 }  
  37.                 //向左边赋值  
  38.                 else if(i<4*n-4){  
  39.                     arr[arr.length-1-(k++)-count][0+count]=++max;     
  40.                 }  
  41.             }  
  42.             //当n为奇数时,存在n=1的情况,最里圈只有一个数  
  43.             if(n==1){  
  44.                 arr[arr.length/2][arr.length/2]=max+1;  
  45.             }  
  46.             //增加圈数  
  47.             count++;  
  48.             //边界每次减少两个数值  
  49.             n -= 2;  
  50.             //递归  
  51.             rec2DArr(arr,n,count,max);  
  52.         }  
  53.     }  
  54.     //打印二维数组  
  55.     public static void print2DArr(int[][] arr){  
  56.         //二维数组需要双重循环打印  
  57.         for(int[] ar : arr){  
  58.             for(int a : ar){  
  59.                 if(a<10)  
  60.                     System.out.print(" "+a+" ");  
  61.                 else  
  62.                     System.out.print(a+" ");  
  63.             }  
  64.             System.out.println();  
  65.         }  
  66.     }  


  67. }
复制代码


想问的问题是,当i为8时,数组是arr[5-1-0][3+0]??????实际应该是arr[3][4]啊,对于8这个临界值,就应该在这个if语句中啊?????


作者: 不系之舟王    时间: 2014-12-30 09:54
是当i的值为8时,也就是在下面这个语句里面
  1. //在下边赋值  
  2.                 else if(i<3*n-3){  
  3.                     arr[arr.length-1-count][(k--)+count]=++max;  
  4.                 }  
复制代码


作者: MengDeKaiShi    时间: 2014-12-30 10:42
确实似乎挺不容易想的
作者: 后悔药    时间: 2014-12-30 12:10
不想看代码了,直接把我的代码贴上吧,注解挺详细的
  1. public class Test9 {

  2.         public static void main(String[] args) {

  3.                 Scanner input = new Scanner(System.in);
  4.                 System.out.println("请输入一个整数: ");
  5.                 //从键盘接收一个整数
  6.                 int n = input.nextInt();

  7.                 int[][] out = test(n);
  8.                
  9.                 //以矩形方式打印数组
  10.                 for (int i = 0; i < n; i++) {
  11.                         for (int j = 0; j < n; j++) {
  12.                                 //每列数据间隔一个制表符
  13.                                 System.out.print(out[i][j] + "\t");
  14.                         }
  15.                         //换行
  16.                         System.out.print("\r\n");
  17.                 }

  18.                 input.close();
  19.         }

  20.         /**
  21.          * 总思路:将二维数组看成一个正方形,先给二维数组上边和右边赋值,再给下边和左边赋值,通过标签flag控制两次赋值的循环
  22.          *
  23.          * @param n
  24.          * @return
  25.          */
  26.         static int[][] test(int n) {
  27.                 int[][] out = new int[n][n];

  28.                 // 定义第一个数
  29.                 int num = 1;

  30.                 // 每次画的行和列的数据的个数,即键盘录入的整数
  31.                 int m = n;

  32.                 // 每次要赋值的行和列
  33.                 int a = 0, b = -1;
  34.                 /**
  35.                  * flag为true就给上边和右边两边赋值, flag为false就给下边和左边两边赋值
  36.                  * */
  37.                 boolean flag = true;

  38.                 // 结束的标记是行和列上的数据个数为0
  39.                 while (m != 0) {
  40.                         for (int i = 0; i < m; i++) {
  41.                                 if (flag) {
  42.                                         //给上边赋值
  43.                                         out[a][++b] = num++;
  44.                                 } else {
  45.                                         //给下边赋值
  46.                                         out[a][--b] = num++;
  47.                                 }
  48.                         }
  49.                        
  50.                         //为第二边赋值时由于两条边在拐角处有重合,所以赋值个数为m - 1
  51.                         for (int i = 0; i < m - 1; i++) {
  52.                                 if (flag) {
  53.                                         // 给右边赋值
  54.                                         out[++a][b] = num++;
  55.                                 } else {
  56.                                         //给左边赋值
  57.                                         out[--a][b] = num++;
  58.                                 }
  59.                         }
  60.                         // 每画完半圈下一次行数和列数上要画的数据数个数减1
  61.                         m--;
  62.                         // 翻转标签
  63.                         flag = !flag;
  64.                 }
  65.                 return out;
  66.         }
  67. }
复制代码

作者: 王者之风西昆仑    时间: 2014-12-30 12:47
好难啊,不会做
作者: 寻觅    时间: 2014-12-30 17:53
你看差了,哥们!i是从0开始的,i是8的时候,数组是arr[4][4]==9,而你说的arr[3][4]==8,对应的i是7

作者: 李增宽    时间: 2014-12-30 23:42
好乱。。。。
作者: l763631191    时间: 2014-12-31 03:42
好难我不会!
作者: 不系之舟王    时间: 2014-12-31 09:28
MengDeKaiShi 发表于 2014-12-30 10:42
确实似乎挺不容易想的

是啊,好多题我都看不懂让干嘛的,瞬间感觉没编程头脑啊。。。。
作者: 不系之舟王    时间: 2014-12-31 09:31
王者之风西昆仑 发表于 2014-12-30 12:47
好难啊,不会做

:handshake
作者: 不系之舟王    时间: 2014-12-31 09:35
寻觅 发表于 2014-12-30 17:53
你看差了,哥们!i是从0开始的,i是8的时候,数组是arr[4][4]==9,而你说的arr[3][4]==8,对应的i是7
...

恩恩,多谢哥们,确实看错了
作者: 不系之舟王    时间: 2014-12-31 09:36
李增宽 发表于 2014-12-30 23:42
好乱。。。。

没怎么在论坛发过贴,代码有点乱了。。。。
作者: 不系之舟王    时间: 2014-12-31 09:39
l763631191 发表于 2014-12-31 03:42
好难我不会!

我也不会。。。。
作者: 不系之舟王    时间: 2014-12-31 09:40
l763631191 发表于 2014-12-31 03:42
好难我不会!

我也不会。。。。
作者: 寻觅    时间: 2014-12-31 09:51
不系之舟王 发表于 2014-12-31 09:35
恩恩,多谢哥们,确实看错了

客气啥,谁都有这样的经历!加油!
作者: 十万一千    时间: 2015-1-1 17:12
http://bbs.itheima.com/forum.php?mod=viewthread&tid=158259
作者: jinghoujiayin    时间: 2015-1-1 18:10
学习学习,不错
作者: jinghoujiayin    时间: 2015-1-1 18:12
学习学习,很不错,希望我能很快的到达这一步
作者: 邓士林    时间: 2015-1-1 18:39
这个其实就是看你滴问题的思考,首先,实现巧妙利用变量来对二位数组进行控制,
     public static void main(String args[])  
  
String strIn="";  
System.out.println("请输入矩阵的行列数:");  
InputStreamReader input=new InputStreamReader(System.in);  
BufferedReader buff=new BufferedReader(input);  
try  
{  
    strIn=buff.readLine();  
}  
catch (IOException ex)  
{  
    System.out.println(ex.toString());  
}  
  
int istr=Integer.parseInt(strIn);  
int n=istr;  
//System.out.println("这是行列数为:"+ n +"螺旋矩阵”);  
int iInit=1;  
int array[][]=new int[n][n];  
int iCondition;  
if(n%2>0)  
{  
    iCondition=n/2+1;  
}  
else  
{  
    iCondition=n/2;  
}  
for(int i=0;i<iCondition;i++)  
{  
    for(int j=i;j<n-i;j++)  
    {  
        array[i][j]=iInit;  
        iInit++;  
    }  
    for(int k=i+1;k<n-i;k++)  
    {  
        array[k][n-i-1]=iInit;  
        iInit++;  
    }  
    for(int l=n-i-2;l>=i;l--)  
    {  
        array[n-i-1][l]=iInit;  
        iInit++;  
    }  
    for(int t=n-i-2;t>i;t--)  
    {  
        array[t][i]=iInit;  
        iInit++;  
    }  
  
    for(int m=0;m<n;m++)  
    {  
        for(int j=0;j<n;j++)  
        {  
            System.out.print(array[m][j]+"   ");  
        }  
        System.out.println();  
    }  
}
作者: Jason996    时间: 2015-1-1 18:52
这个题我没有做出来,原来要用二维数组。学习




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