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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

//我是深圳0422期的学员,舍友有次提到这道题目,我就按自己的理解思路写了出来
//这个程序经过多次测试,暂时没发现BUG【按要求输入行列】
//问题来了---------个人感觉代码过于繁琐------有木有更好的解决方法?【任意行任意列】
import java.util.Scanner;
/**
*实现螺旋矩阵--------
*思路:1.将螺旋矩阵分成了4种情况  首先是往右走,然后是往下走,然后是往左走,然后是往上走,然后再往右走。。。。。
*      2.往右走:首先往右走,如果发现右边这样走是错的【超出数组界限或者右边已经有数了】,就退回,走对了就标记下【给标记数组赋值,同时记录坐标】
*                 然后要往下走,如果发现下边是不可以走的【超出数组界限或者下边已经有数了】,就不走了
*    3.往下走:首先往下走,如果发现下边这样走是错的【超出数组界限或者下边已经有数了】,就退回,走对了就标记下【给标记数组赋值,同时记录坐标】
*                 然后要往左走,如果发现左边是不可以走的【超出数组界限或者左边已经有数了】,就不走了
*    4.往左走:首先往左走,如果发现左边这样走是错的【超出数组界限或者左边已经有数了】,就退回,走对了就标记下【给标记数组赋值,同时记录坐标】
*                 然后要往上走,如果发现上边是不可以走的【超出数组界限或者上边已经有数了】,就不走了
*    5.往上走:首先往上走,如果发现上边这样走是错的【超出数组界限或者上边已经有数了】,就退回,走对了就标记下【给标记数组赋值,同时记录坐标】
*                 然后要往右走,如果发现右边是不可以走的【超出数组界限或者右边已经有数了】,就不走了
*   
*@version 1.0
*@author 深圳0422期学员:黄**
*/

class LuoXuan {
public static void main(String []args) {
   Scanner scanner=new Scanner(System.in);
   int hs;//输入行数
   int ls;//输入列数
   int key=0;//递加的值
   System.out.print("请输入行数:");
   hs=scanner.nextInt();
    System.out.print("请输入列数:");
   ls=scanner.nextInt();
  int [][]a=new int [ls][hs];//保存数组
  int [][]b=show(ls,hs);//获取坐标数组
  System.out.println("输入1:外循环,其它任意:内循环:");
  System.out.print("请选择模式:");
  if(scanner.next().equals("1"))
  {
   for(int i=b.length-1;i>=0;i--)//外循环矩阵
    a[b[0]][b[1]]=++key;
  }else
  {
   for(int i=0;i<b.length;i++)//内循环矩阵
    a[b[0]][b[1]]=++key;
  }
  for(int y=0;y<hs;y++)//双for输出a数组的所有值
  {
   for(int x=0;x<ls;x++)
    System.out.print(a[x][y]+"\t");
   System.out.println("\n");
  }
  
}
  
/**
*获取指定行数跟列数内循环螺旋的坐标数组
*@param x 输入的列数,也可以理解为X坐标
*@param y 输入的行数  也可以理解为Y坐标
*/
  
public static int [][]  show(int x,int y) {

  
  int x1=-1,y1=0;//走的坐标
  int zt=1;//行走的状态 1代表往右走 2代表往下走 3代表往左走 4代表往上走
  int [][]a=new int [x][y];//记录坐标是否走过
  int [][]b=new int [x*y][2];int js=-1;//保存坐标
   x--;y--;//将列数跟行数转换为索引对应的最值
  do
  {
    if(zt==1) {//往右走
    x1++;//往右走
    if(x1>x||a[x1][y1]!=0) {//如果往右走,超出范围了,或者右边不可以走,代表走失败
     x1--;//走失败,退回
     if( y1+1>y||a[x1][y1+1]!=0)//如果往下走超出范围,或者下面已经有数了,就退出循环
      break; else zt++;//否则往下走
    } else {
      a[x1][y1]=1;//记录该坐标已被走过
      b[++js][0]=x1;//保存走的x坐标
      b[js][1]=y1;//保存走的y坐标
      }
   
    }
     if(zt==2) {//往下走
    y1++;//往下走
    if(y1>y||a[x1][y1]!=0) {//如果往下走,超出范围了,或者下边不可以走,代表走失败
      y1--;//走失败,退回
     if(x1-1<0||a[x1-1][y1]!=0)//如果往左走超出范围,或者下面已经有数了,就退出循环
      break;else zt++;//否则往左走
    } else {
     a[x1][y1]=1;//记录该坐标已被走过
      b[++js][0]=x1;//保存走的x坐标
      b[js][1]=y1;//保存走的y坐标
      }
    }
     if(zt==3) {//往左走
    x1--;//往左走
    if(x1<0||a[x1][y1]!=0) {//如果往左走,超出范围了,或者左边不可以走,代表走失败
     x1++;//走失败,退回
     if(y1-1<0||a[x1][y1-1]!=0)//如果往上走超出范围,或者下面已经有数了,就退出循环
      break; else zt++;//否则往上走
    } else {
      a[x1][y1]=1;//记录该坐标已被走过
      b[++js][0]=x1;//保存走的x坐标
      b[js][1]=y1;//保存走的y坐标
      }
    }
     if(zt==4) {//往上走
    y1--;//往上走
    if(y1<0||a[x1][y1]!=0) {//如果往上走,超出范围了,或者上边不可以走,代表走失败
      y1++;//走失败,退回
     if(x1+1>x||a[x1+1][y1]!=0)//如果往右走超出范围,或者右面已经有数了,就退出循环
      break; else zt=1;//否则往右走
    } else {
      a[x1][y1]=1;//记录该坐标已被走过
      b[++js][0]=x1;//保存走的x坐标
      b[js][1]=y1;//保存走的y坐标
      }
    }
  }
  while (true);
  return b;
}
}


QQ截图20150429210808.png (3.09 KB, 下载次数: 6)

QQ截图20150429210808.png

QQ截图20150429210830.png (37.34 KB, 下载次数: 7)

QQ截图20150429210830.png

QQ截图20150429210849.png (8.53 KB, 下载次数: 6)

QQ截图20150429210849.png

2 个回复

正序浏览
我们19期班的大神啊!赞!
回复 使用道具 举报
不错,有些知识我没学到
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马