黑马程序员技术交流社区

标题: 螺旋打印方阵的题目,谁会? [打印本页]

作者: doevents    时间: 2013-10-8 10:24
标题: 螺旋打印方阵的题目,谁会?
写一方法,打印等长的二维数组,要求从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列。
* 如: n = 4 则打印
*  1  2   3   4
* 12 13 14 5
* 11 16 15 6
* 10  9  8   7
谁有思路的附上代码,有思路更好。

作者: loading……99.9    时间: 2013-10-8 11:15
我是这样做的,根据螺旋方式,先为第一行前n-1一个数赋值,然后为最后一列前n-1个数字赋值,接着为最后一行后n-1个数字赋值,最后为第一列后n-1个数字赋值,然后递归调用为内层赋值,我这种做法只能为偶数能行,当n=2n + 1的时候,就要特殊考虑需要为行竖最中间的值手动赋值。
  1. public class Test9
  2. {
  3.         private int wid = 4;
  4.        
  5.         private int[][]arr;
  6.        
  7.         public static void main(String[] args)
  8.         {
  9.                 Test9 test9 = new Test9(6);
  10.                
  11.                 test9.output();
  12.         }
  13.        
  14.         public Test9(int num)
  15.         {
  16.                 if(num > 0)
  17.                 {
  18.                         wid = num;
  19.                 }
  20.                 else
  21.                 {
  22.                         System.out.println("数据不合法,则使用默认的值。");
  23.                 }
  24.                 //通过构造函数num的值可以得出将要输出的是一个num * num的矩阵
  25.                 arr = new int[this.wid][this.wid];
  26.                
  27.                 if(num % 2 != 0)
  28.                 {
  29.                         //解决当num为奇数,for循环不能为 整个矩阵横竖中间的数字赋值的情况
  30.                         arr[num / 2][num / 2] = num * num;
  31.                 }
  32.                
  33.                 assignment(0,1);
  34.         }
  35.        
  36.         public void assignment(int roll ,int start)
  37.         {
  38.                 if(roll > this.wid)
  39.                 {
  40.                         return;
  41.                 }
  42.                
  43.                 for(int i = 0; i < this.wid - 2 * roll -1 ; i ++) //为数组第一行前wid - roll - 1个数据赋值 arr[roll][roll] ---- arr[roll][this.wid - 2 * roll -2]
  44.                 {
  45.                         this.arr[roll][roll + i] = start;
  46.                         start ++;
  47.                 }
  48.                
  49.                 if(start > wid * wid) return; //当下一个该赋值数据大于 num * num 时候跳出循环
  50.                
  51.                 for (int i = 0; i < this.wid- 2* roll -1; i++)//为数组最后一排前wid - roll - 1个数据赋值 arr[roll][this.wid - 2 * roll -1] ---- arr[this.wid- 2 * roll -2][this.wid - 2 * roll -1]
  52.                 {
  53.                         this.arr[roll + i][this.wid - roll - 1] = start;
  54.                         start ++;
  55.                 }
  56.                
  57.                 if(start > wid * wid) return;
  58.                
  59.                 for(int i = this.wid - 2* roll - 1; i > 0; i --)//为数组最后-行后wid - roll - 1个数据赋值arr[this.with - 2 * roll -1][this.wid - 2 * roll -1] ---- arr[this.wid - 2 * roll -1][roll + 1]
  60.                 {
  61.                         this.arr[this.wid - roll - 1][roll + i] = start;
  62.                         start ++;
  63.                 }
  64.                
  65.                 if(start > wid * wid) return;
  66.                
  67.                 for(int i = this.wid - 2 * roll - 1; i > 0; i --)//为数组第一排后 wid - roll -1 个数据赋值arr[this.wid - 2 * roll - 1][roll] ---- arr[roll + 1][roll]
  68.                 {
  69.                         this.arr[roll + i][roll] = start;
  70.                         start ++;
  71.                 }
  72.                
  73.                 if(start > wid * wid) return;
  74.                 //递归调用,刚才进行了外围的赋值,现在进入内围的赋值
  75.                 assignment(++ roll, start);
  76.         }
  77.        
  78.         public void output()
  79.         {
  80.                 for (int i = 0; i < arr.length; i++)
  81.                 {
  82.                         for (int j = 0; j < arr.length; j++)
  83.                         {
  84.                                 System.out.print("        " + arr[i][j]);//打印输出每一个数据
  85.                         }
  86.                         //每打印一行换行
  87.                         System.out.println();
  88.                 }
  89.         }
  90. }
复制代码

作者: 第一印象    时间: 2013-10-8 11:33
这不是入学考试的面试题吗?
作者: jìng╮煜    时间: 2013-10-8 14:01
本帖最后由 jìng╮煜 于 2013-10-8 14:03 编辑
  1. import java.io.*;

  2. class  roll
  3. {         
  4.         public static void main(String[] args) throws Exception
  5.         {
  6.                 BufferedReader bufr=
  7.                         new BufferedReader(new InputStreamReader(System.in));
  8.                 int buf=new Integer(bufr.readLine());

  9.                 int[][] arr=new int[20][20];
  10.                 System.out.println("buf="+buf);
  11.                 int row1=1,col1=1;
  12.                 int i=1,j=1,k=1;
  13.                 int row,col;
  14.                 row=col=buf;
  15.                 do{
  16.                         for(;i<row;i++)
  17.                         arr[j-1][i-1]=k++;
  18.                         row--;
  19.                         for(;j<col;j++)
  20.                         arr[j-1][i-1]=k++;
  21.                         col--;
  22.                         for(;i>col1;i--)
  23.                         arr[j-1][i-1]=k++;
  24.                         col1++;
  25.                         for(;j>row1;j--)
  26.                         arr[j-1][i-1]=k++;
  27.                         row1++;
  28.                         i++;j++;
  29.                 }while(row1<row&&col1<col);
  30.                 arr[i-1][j-1]=k;
  31.                 for(i=0;i<buf;i++){
  32.                         for(j=0;j<buf;j++)
  33.                         {
  34.                         System.out.print(arr[i][j]+"\t");
  35.                         }
  36.                         System.out.println();
  37.                         }
  38.         }
  39. }
复制代码

作者: jìng╮煜    时间: 2013-10-8 14:09
要思路就回复我.
作者: 张慧    时间: 2013-10-8 15:07
  1. /**
  2. * 思路:把一个矩阵看做是一个个正方形套在一起,由最外边的那个正方形开始去赋值。因为这个赋值的过程是
  3. * 重复去操作,而且正方形的个数如果不是很多,可以考虑递归。正方形的个数(len/2)(其中len是矩阵的
  4. * 边长)。在遍历的每一个正方形的起点的位置就是上一个正方形终点的列值加1,起点的值就是上一个正方形
  5. * 终点的值加1.
  6. *
  7. * 注:代码里可以指定矩阵的边长的,不一定要是正方形矩阵,也可以是长方形矩阵(思路里是真的正方形写的,
  8. * 长方形可他其实是一样的)。
  9. */
  10. public class Test2 {
  11.         public static int[][] array = new int[10][10];

  12.         public static void main(String[] args) {
  13.                 int x_len = 5;
  14.                 int y_len = 7;
  15.                 putValues(x_len,y_len, 0, 0, 1);
  16.                 printlnArray(x_len,y_len);
  17.         }

  18.         public static void putValues(int x_len,int y_len, int x, int y, int first_value) {
  19.                 //如果边长为1,说明就一个值,直接赋值即可,然后return出去(递归的出口)
  20.                 if (x_len == 1) {
  21.                         for(int i=0;i<y_len;i++){
  22.                                 array[x][y++] = first_value++;
  23.                         }
  24.                         return;
  25.                 }
  26.                 array[x][y] = first_value;
  27.                 //上,右,下,左 循环给数组赋值(这样的顺序是因为值都是在累加的)
  28.                 for (int j = 0; j < y_len-1; j++) {
  29.                         array[x][++y] = ++first_value;
  30.                 }
  31.                 for (int j = 0; j < x_len-1; j++) {
  32.                         array[++x][y] = ++first_value;
  33.                 }
  34.                 for (int j = 0; j < y_len-1; j++) {
  35.                         array[x][--y] = ++first_value;
  36.                 }
  37.                 for (int j = 0; j < x_len-2; j++) {
  38.                         array[--x][y] = ++first_value;
  39.                 }
  40.                 //判断矩阵的变长是否>=1(如果是,继续给内部的方形赋值)递归
  41.                 if(x_len -2>=1){
  42.                         putValues(x_len - 2,y_len-2, x, ++y, ++first_value);
  43.                 }
  44.                
  45.         }

  46.         public static void printlnArray(int x_len,int y_len) {
  47.                 for (int i = 0; i < x_len; i++) {
  48.                         System.out.print("*");
  49.                         for (int j = 0; j < y_len; j++) {
  50.                                 System.out.print(array[i][j] + " ");
  51.                         }
  52.                         System.out.println("");
  53.                 }
  54.         }
  55. }
复制代码
对长方形矩阵可以满足螺旋打印。。。{:soso_e100:}
作者: 张俊生    时间: 2013-10-8 20:03
这个题我也有

作者: hx32    时间: 2013-10-9 00:43
@乔兵,这是入学测试题啊,可以这么问的?还给加分?
作者: doevents    时间: 2013-10-9 10:43
张俊生 发表于 2013-10-8 20:03
这个题我也有

想了半天才写完,:(,有难度这题
作者: 编程的梦想    时间: 2013-12-8 20:58
jìng╮煜 发表于 2013-10-8 14:01

为什么这个代码在运行时输入n=4时,该出现数字15的位置反而出现17呢,而n=5时,输出就正确了,不解???
作者: 道逍云心    时间: 2014-1-4 21:14
public class Test9 {
  public static void main(String[] args){
   //定义数组的长度
   
    int len = 10;
   
    //调用得到螺旋数组的方法
   
   int[][] arys = getSpiralArray(len);
   
    //用for循环嵌套,对数组进行遍历输出
   
    for (int i = 0; i < len; i++)
     {
      for (int j = 0; j < len; j++)
      {  
   
       System.out.print(arys[i][j] + "\t");
      }
        System.out.println();
    }
  }

public static int[][] getSpiralArray(int length) {
  //定义一个等长度的数组
  
  int[][] array = new int[length][length];
  
  int upcol = 0;
  
  //向右走列数
  
  int leftRow = 0;
  
  //记录最后一行的变量
  
  int downCol = length-1;
  
  //记录最后一列的变量
  
  int rightRow = length-1;
  
  int num = 1;
  while(length > 0){
   
   //向右走,循环遍历,并把得到的值添加到数组中
   
   for(int i = 0, temp = leftRow; i < length; i++){
   
    //第一行,打印向右走,随着列数的的自增1,第一行的元素也随着自增1
   
    array[upcol][temp++] = num++;      
   }     
   //向下走,循环遍历,并把得到的值添加到数组中
   
   for(int i = 0, temp =  leftRow+1; i < length-1; i++){
   
    //最后一列,打印向下走,随着行数的自增1,最后一列的元素也自增1
   
    array[temp++][downCol] = num++;
   }
   
   //向左走,循环遍历,并把得到的值添加到数组中,是从length-1列的最后一个元素开始,所以是rightRow-1
   
   for(int i = 0, temp = rightRow-1; i < length-1; i++){
   
    //最后一行,打印向左走,随着列数的自减1,最底层的元素自增1
   
    array[downCol][temp--] = num++;
   }   
   //向上走,循环遍历,并把得到的值添加到数组中  ,是从length-1行的最后一个元素开始,所以是downCol-1
   
   for(int i = 0, temp =downCol-1; i< length-2; i++){
   
    //最左边一列,向上打印,随着行数的自减1,最左边的一列中的元素自增1
   
    array[temp--][upcol] = num++;
   }
   //再往里边依次循环,直到打印到最后的一个数就是length的平方
   
   //每打印最外面的一圈,内圈的长度减少2
   
   length = length - 2;
   
   //向右走的行数增加1,也就是说第二轮循环是从第二行、第二列、length-1行、length-1列
   upcol++;
   leftRow++;
   downCol--;
   rightRow--;
  }  
  return array;
}  

}
作者: 严旭晟    时间: 2014-2-23 15:08
/*
* 本题要求顺时针旋转,即考查方向问题
* 题目的方向路径:L->R,U->D,R->L,D->U
* 需注意:1.水平方向运动,行标不变;垂直方向运动,列表不变
*         2.转角处,注意变化,主要是缩距
*         3.二维整型数组求长度
* Created by Ian Feyman
* */
//按水平方向和垂直方向坐标分析
作者: 严旭晟    时间: 2014-2-23 15:13
按照这个思路,代码量少




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