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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 郑飞 高级黑马   /  2014-9-5 03:04  /  12108 人查看  /  23 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 郑飞 于 2014-9-5 04:05 编辑

分享入学测试题 , 不知道代码还能不能再优化,或者有没其他简单方法 :
  1. /*
  2. 1、 写一方法,打印等长的二维数组,要求从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列。 如: n = 4 则打印:                                
  3. 1        2        3        4
  4. 12        13        14        5
  5. 11        16        15        6
  6. 10        9        8        7
  7. 思路和步骤:
  8.         1:利用二维数组 列为里面的一维数组
  9.         2:给元素赋值 依题意可知方阵开始走动,必然有一边是被堵住 而且纵横交替因此 定义两个方法 一个横向一个纵向
  10.           横向:左右都走一遍 而后转入纵向 如此循环 利用最大元素值n的平方来控制跳出循环
  11.         3:跳出循环时必然赋值完毕,打印二维数组.
  12. */
  13. class Exam1
  14. {        
  15.         private static String insert = "";
  16.         public static void main(String[] args)
  17.         {
  18.                 test(4);
  19.         }        
  20.                 //横向赋值的时候 必然有一边是被堵的
  21.         public static void setX(int[][] arr,int x,int y,int count)
  22.         {
  23.                 if(arr[x][y]==arr.length*arr.length)//如果走到头了就退出
  24.                         return;
  25.                 if((x+1)<arr.length)//向右边走
  26.                 {
  27.                         while(arr[x+1][y]==0)
  28.                         {
  29.                                 arr[x+1][y] = count++;
  30.                                 x++;
  31.                                 if((x+1)>=arr.length)
  32.                                         break;
  33.                         }
  34.                 }
  35.                 if((x-1)>=0)//向左走
  36.                 {
  37.                         while(arr[x-1][y]==0)
  38.                         {
  39.                                 arr[x-1][y] = count++;
  40.                                 x--;
  41.                                 if((x-1)<0)
  42.                                 break;
  43.                         }
  44.                 }
  45.                 setY(arr,x,y,count);//调用纵向方法
  46.         }
  47.                 public static void setY(int[][] arr,int x,int y,int count)
  48.         {
  49.                 if((y+1)<arr[x].length)//直接向下走
  50.                 {
  51.                         while(arr[x][y+1]==0)
  52.                         {
  53.                                 arr[x][y+1] = count++;
  54.                                 y++;
  55.                                 if((y+1)>=arr[x].length)
  56.                                         break;
  57.                         }
  58.                 }
  59.                 if((y-1)>=0)//向上走
  60.                 {
  61.                         while(arr[x][y-1]==0)
  62.                         {
  63.                                 arr[x][y-1] = count++;
  64.                                 y--;
  65.                                 if((y-1)<0)
  66.                                         break;
  67.                         }
  68.                 }
  69.                 setX(arr,x,y,count);//调用横向方法
  70.         }
  71.         
  72.         public static void test(int n)
  73.         {
  74.                 int[][] arr = new int[n][n];//初始化二维数组
  75.                 arr[0][0] = 1;//给第一个元素赋值(因为set方法中是从第二个元素开始赋值)
  76.                 setX(arr,0,0,2);//从x=0,y=0位置开始,第二个元素开始赋值,所以count传入2.
  77.                 printArr(arr);//打印数组
  78.         }

  79.         public static void printArr(int[][] arr)
  80.         {
  81.                 for (int x=0;x<arr[0].length ;x++ )//遍历打印二维数组
  82.                 {
  83.                         for (int y=0;y<arr.length ;y++ )
  84.                         {
  85.                                 System.out.print(blank(arr,arr[y][x])+arr[y][x]+" ");//打印插入空格后的元素
  86.                                 insert = "";
  87.                         }
  88.                         System.out.println("");//打印所有第二维某一行后,换行.
  89.                 }
  90.         }

  91.         public static String blank(int[][] arr,int value)//传入当前数组和当前元素值,返回该插入的空格.
  92.         {
  93.                         int len = (arr.length*arr.length+"").length();//得到该数组最大值该有的长度
  94.                         len = len - (value+"").length();//得到该插入的空格数
  95.                         while (len>=0)//添加空格
  96.                         {
  97.                                 insert = insert+" ";
  98.                                 len--;
  99.                         }
  100.                         return insert;
  101.         }
  102. }
复制代码



点评

嗯 谢谢 之前也想过每条边的做 现在正好做个参考  发表于 2016-6-27 23:59

23 个回复

倒序浏览
  1. import java.util.Scanner;
  2. public class Test9 {
  3. public static void main(String[] args) {  
  4.         
  5.         System.out.println("请输入一个数,来作为您的二位数组维度:");//从键盘接收一个数,动态确定数组大小   
  6.         Scanner sc = new Scanner(System.in);  
  7.         int num = sc.nextInt();
  8.         printArray(num);
  9. }
  10.         public static void printArray(int num){
  11.                
  12.                 int[][] arr = new int[num][num];//根据输入的值,初始化一个num阶的数组,数组里的元素都初始化为0
  13.                 for(int i=0;i<num;i++){  
  14.                         for(int j=0;j<num;j++)  
  15.                         arr[i][j] = 0;  
  16.                 }  
  17.                 int cycles = num/2+num%2;//循环的总圈数
  18.                 int count = 1;//圈数计数器
  19.                 int step = 1;//初始化数字
  20.                 while(count<=cycles){
  21.                         int min = count-1;//最小坐标
  22.                         int max = num-count;//最大坐标
  23.                         if(min==max){
  24.                                 arr[cycles-1][cycles-1]=step;//数组阶数是奇数时,最后一圈不是圈,只有一个点。这里直接对这个点赋值。
  25.                         }
  26.                         else{
  27.                                 //第一条边
  28.                                 for(int a=min;a<=max;a++){
  29.                                         arr[min][a]=step++;
  30.                                 }
  31.                                 //第二条边
  32.                                 for(int b=min+1;b<=max;b++){
  33.                                         arr[b][max]=step++;
  34.                                 }
  35.                                 //第三条边
  36.                                 for(int c=max-1;c>=min;c--){
  37.                                         arr[max][c]=step++;
  38.                                 }
  39.                                 //第四条边
  40.                                 for(int d=max-1;d>=min+1;d--){
  41.                                         arr[d][min]=step++;
  42.                                 }
  43.                         }
  44.                         count++;
  45.                 }        
  46.                 //输出数组
  47.                 for(int m=0;m<num;m++){  
  48.                         for(int n=0;n<num;n++){  
  49.                                 System.out.print(arr[m][n]+"\t");  
  50.                         }         
  51.                         System.out.println("");  
  52.                 }  
  53.         }  
  54. }
复制代码
回复 使用道具 举报
加空格的程序用制表符就可以搞定了!
回复 使用道具 举报
huanglyhf 发表于 2014-9-5 08:53
加空格的程序用制表符就可以搞定了!

嗯 谢谢 之前也想过每条边的做 感觉有点难 就放弃了 现在正好看看
回复 使用道具 举报
  1. public class Test9 {
  2.         public static void main(String[] args) {
  3.                 // 根据n创建一个二维数组
  4.                 int n = 8;
  5.                 int[][] arr = new int[n][n];
  6.                 // 调用数组赋值的方法
  7.                 method(arr);
  8.                 // 将数组遍历出来
  9.                 for (int i = 0; i < arr.length; i++) {
  10.                         for (int j = 0; j < arr.length; j++) {
  11.                                 System.out.print(arr[i][j] + "\t");
  12.                         }
  13.                         System.out.println("\n");
  14.                 }

  15.         }

  16.         // 二维数组赋值方法
  17.         public static void method(int[][] arr) {
  18.                 // 创建数组的两个索引变量
  19.                 int i = 0;
  20.                 int j = 0;
  21.                 // 通过 max 和min控制索引i,j的变化
  22.                 int max = arr.length - 1;
  23.                 int min = 0;
  24.                 // 所需要赋的值
  25.                 int num = 1;

  26.                 while (min <= max) {
  27.                         // 1、i不变j++ 向右
  28.                         while (j < max) {
  29.                                 arr[i][j++] = num++;
  30.                         }
  31.                         // 2、j不变i++ 向下
  32.                         while (i < max) {
  33.                                 arr[i++][j] = num++;
  34.                         }
  35.                         // 3、i不变j-- 向左
  36.                         while (j > min) {
  37.                                 arr[i][j--] = num++;
  38.                         }
  39.                         // 4、j不变i-- 向上
  40.                         while (i > min) {
  41.                                 arr[i--][j] = num++;
  42.                         }
  43.                         // 由于可能在n为奇数的时候无法为中心那个数赋值所以要补上这个数的赋值
  44.                         if (min == max) {
  45.                                 arr[i][j] = num;
  46.                         }
  47.                         max--;
  48.                         min++;
  49.                         // 循环一圈又开始想有赋值j++
  50.                         j++;
  51.                         // 由于向上的时候最后一次赋值i多减了一次所以每次外循环都要将i补回来
  52.                         i++;
  53.                 }
  54.         }
  55. }
复制代码
回复 使用道具 举报 7 0
直接从1循环到N^2,i,j代表二维数组下标,初始值为0,二维数组也全部初始化为0。每次输出一个值:如果i=0或a[i-1][j]>0,则往右走;如果j=N-1或a[i][j+1]>0,则往下走;如果i=N-1或a[i+1][j]>0,则往左走;如果j=0或a[i][j-1]>0,则往上走。这样代码看起来会清楚很多
回复 使用道具 举报
学习了。。。。。
回复 使用道具 举报

谢谢 分享 思路和代码都很简练 用while看起来很清爽啊 哈哈 :handshake
回复 使用道具 举报
我只适合被遗忘 来自手机 中级黑马 2015-3-11 18:10:32
9#
好难啊,还没学到数组怎么破
回复 使用道具 举报
不错啊!
回复 使用道具 举报
我也发个我写的~
package pack;

public class LuoXuan {

        /**
         * @param args
         */
        public static void main(String[] args) {
                func(5);
        }
       
        public static void func(int n)
        {
                int i=0,j=0,value=0;
                int arr[][]=new int[n][n];
                if(n%2==0)
                        arr[n/2][n/2-1]=n*n;
                else
                        arr[n/2][n/2]=n*n;
                for(j=0;j<n-1;j++)
                        arr[0][j]=++value;
                while(n>1)
                {
                        for(int x=0;x<n-1;x++)
                                arr[i++][j]=++value;
                        for(int x=0;x<n-1;x++)
                                arr[i][j--]=++value;
                        n--;
                        for(int x=0;x<n-1;x++)
                                arr[i--][j]=++value;
                        for(int x=0;x<n-1;x++)
                                arr[i][j++]=++value;
                        n--;
                }
               
               
                for(int ii=0;ii<arr.length;ii++)
                {
                        for(int jj=0;jj<arr[i].length;jj++)
                        {
                                System.out.print(arr[ii][jj]+"\t");
                        }
                        System.out.println();
                }
        }
}
回复 使用道具 举报
方法好多
回复 使用道具 举报
  1. package com.itheima;
  2. /**
  3. *第9题:写一方法,打印等长的二维数组,要求从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列。
  4. * 如: n = 4 则打印:  
  5. * 1         2         3         4
  6. * 12 13 14 5
  7. * 11 16 15 6
  8. * 10         9         8         7      
  9. * @author zl
  10. *思路:给二维数组赋值的方法,一圈一圈地从外到内赋值,一圈即一个循环。
  11. *详细:设为n维、h圈
  12. *一,nxn维数组有h((n+1)/2)圈,循环从外到内圈依次赋值;
  13. *二,每圈由上、下行和左、右列共四个臂组成,按照上、右、下、左臂的先后顺序依次循环赋值;
  14. *三,每个臂有元素n-h-(h-1)个,每臂以一个四角元素为起始元素依次赋值;
  15. *四,四角元素索引分别为[h-1][h-1]、[h-1][n-h]、[n-h][n-h]、[n-h][h-1]。
  16. *
  17. *以n=4为例进行具体说明,此时h=2
  18. *一共2圈;
  19. *第1圈每臂有元素3个;第2圈每臂有元素2个;
  20. *第1圈四角元素(每臂起始)分别为[0][0]、[0[3]、[3][3]、[3][0];
  21. *第1圈赋值顺序依次为:
  22. *上臂元素为[0][0]、[0[1]、[0][2];右臂元素为[0][3]、[1[3]、[2][3];
  23. *下臂元素为[3][3]、[3[2]、[3][1];左臂元素为[3][0]、[2[0]、[1][0];
  24. *第2圈赋值顺序依次为
  25. *上臂元素为[1][1];右臂元素为[1][2];
  26. *下臂元素为[2][2];左臂元素为[2][1];
  27. *
  28. *注意一个特例:即最后一圈为一个元素时,需要做点例外处理。
  29. */
  30. public class Test09_2DArray {

  31.         public static void main(String[] args) {
  32.                 // 定义螺旋形二维数组并打印
  33.                 int[][] arr = helixArray(6);
  34.                 printArr(arr);
  35.         }

  36.         //定义静态方法,返回n行n列的螺旋形二维数组;
  37.         static int[][] helixArray(int n) {
  38.                 //定义二维数组、圈数和第一个元素的值
  39.                 int[][] helArr = new int[n][n];
  40.                 int helLen = (n+1)/2 ;
  41.                 helArr[0][0] = 1;
  42.                 //初始化; 从外圈到内圈依次赋值
  43.                 for(int h=1; h<=helLen; h++) {
  44.                         // 给第h圈的上臂[h-1]行的元素赋值;从第一列[h-1]到倒数最后一列[n-h-1];第一圈与其他圈稍有不同,分开处理;
  45.                         //考虑到最后一圈的元素可能只有一个,即每行或列的第一个元素与最后一个元素重合,因此有必要遍历到上行的最后一个元素[n-h];
  46.                         //如果不遍历到最后一个元素,则n为奇数即最后一圈为一个元素时,最后一个元素将得不到赋值。
  47.                         for(int j=h-1; j<=n-h; j++) {
  48.                                 if(h==1) {
  49.                                         // 公式中helArr[h-1][h-1]是第1圈上臂行左边第一个元素,第一圈其余元素值根据第一个元素值依次获得
  50.                                         helArr[h-1][j] = helArr[h-1][h-1] + j - (h - 1);
  51.                                 } else {
  52.                                         // helArr[h-1][h-2]是第h-1圈左臂列上面第一个元素,即非第一圈元素值根据第一圈最后一个元素值获得
  53.                                         helArr[h-1][j] = helArr[h-1][h-2] + 1 + j - (h-1) ;
  54.                                 }
  55.                         }
  56.                        
  57.                         //给第h圈的右臂[n-h]列元素赋值;从第一行[h-1]到倒数最后一行[n-h-1]
  58.                         for(int i=h-1; i<=n-h-1; i++) {
  59.                                 // helArr[h-1][n-h-1]是第h圈上臂最后一个元素
  60.                                 helArr[i][n-h] = helArr[h-1][n-h-1]+1 + i - (h - 1);
  61.                         }

  62.                         //给第h圈的下臂[n-h]行元素赋值;从右边第一列[n-h]向左到倒数第二列[h]
  63.                         for(int j=n-h; j>=h; j--) {
  64.                                 // helArr[n-h-1][n-h]是第h圈右右臂的最后一个元素
  65.                                 helArr[n-h][j] = helArr[n-h-1][n-h]+ 1 + n-h- j;
  66.                         }

  67.                         //给第h圈的左侧列[h-1]元素赋值,从左侧列倒数第一行[n-h]向上到第二行[h]
  68.                         for(int i=n-h; i>=h; i--) {
  69.                                 // helArr[n-h][h]是第h圈下臂最后一个元素
  70.                                 helArr[i][h-1] = helArr[n-h][h] + 1 + n - h - i;
  71.                         }
  72.                 }
  73.                
  74.                 return helArr;
  75.         }
  76.        
  77.        
  78.         //定义静态方法,打印二维数组; 添加制表符,对齐数组
  79.         static void printArr(int[][] arr) {
  80.                 for(int i=0; i<arr.length; i++) {
  81.                         for(int j=0; j<arr[i].length; j++) {
  82.                                 System.out.print(arr[i][j]+"\t");
  83.                         }
  84.                         //一行打印完,执行转行
  85.                         System.out.println();
  86.                 }
  87.         }
  88. }
复制代码


回复 使用道具 举报
回复 使用道具 举报

这个代码是最简单的,顶了。
回复 使用道具 举报
本帖最后由 freshnboy 于 2016-3-31 16:13 编辑

我也写了一个,不过思路麻烦了一些。把二维数组看做地图上的点,然后把这个当做路径问题。
每一个地图点都有三个属性:坐标(x,y)、通行性(true/false)、位移矢量(dx,dy)。

规则是从(0,0)出发之后,一直直行(下一点坐标=本坐标+位移矢量),遇到无法通行的情况就向右拐(下一点坐标=本坐标+右转位移矢量)。

然后遍历到计数器=n*n为止。没有什么需要特殊处理的点。

这种方法缺点是代码量明显增加,看起来也不容易一眼看清。
优点是可以处理任意规则的转法,你喜欢S形也能给你走出来
回复 使用道具 举报

这个是我认为最好理解又最方便的方法   怒赞
回复 使用道具 举报

数组的方法厉害。
回复 使用道具 举报
66666,好赞
回复 使用道具 举报
yuzt 中级黑马 2016-10-4 16:26:45
20#
还没想明白,仔细研究下
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马