Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1524360
  • 博文数量: 399
  • 博客积分: 8508
  • 博客等级: 中将
  • 技术积分: 5302
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-14 09:28
个人简介

能力强的人善于解决问题,有智慧的人善于绕过问题。 区别很微妙,小心谨慎做后者。

文章分类

全部博文(399)

文章存档

2018年(3)

2017年(1)

2016年(1)

2015年(69)

2013年(14)

2012年(17)

2011年(12)

2010年(189)

2009年(93)

分类: LINUX

2010-09-15 10:49:45

所谓的螺旋矩阵,指如下形式的H列*L行的矩阵:


    如何编程产生呢,上曾经有不少爱好者给出过自己的解答,这里选两个易理解算法的程序学习。

一、方法一

沿如图方向,沿各个矩形边框依次给矩阵的每一个元素赋值,在计算机内存中构造一个完整的螺旋矩阵,然后输出。

代码:

public class Test { 
 public static int[][] makeMatrix(int w, int h) { 
   int[][] mtr = new int[w][h]; 
   int d = 1, x = 0, y = 0; 
   while(true) { 
     mtr[x][y] = d++; 
     //各方向可否前进 
     boolean right = x< w-1&&mtr[x+1][y]==0; 
     boolean down = y< h-1&&mtr[x][y+1]==0; 
     boolean left = x>0&&mtr[x-1][y]==0; 
     boolean up = y>0&&mtr[x][y-1]==0; 
     //判断前进方向 
     if(right) if(up) y--; else x++; 
     else if(down) if(right) x++; else y++; 
     else if(left) if(down) y--; else x--; 
     else if(up) if(left) x--; else y--; 
     else break; 
   } 
   return mtr; 
 } 
  
 public static void printMatrix(int[][] mtr) { //输出
   int w = mtr.length; 
   int h = mtr[0].length; 
   for(int i=0; i< h; i++) { 
     for(int j=0; j< w; j++) { 
       System.out.print(mtr[j][i] + "\t"); 
     } 
     System.out.println (); 
   } 
 } 
  
 public static void main(String[] args) { 
   int h = Integer.parseInt(args[0]);
   int w = Integer.parseInt(args[1]);
   printMatrix(makeMatrix(h,w)); 
 } 
} 

二、方法二

    做出数学模型, 直接计算每一个坐标上的值, 这样就不用存放一个完整的矩阵在内存中, 要频繁引用的话,可以调用这个算法预先生成一个矩阵存起来。
代码:

/*
* 作者:yanjj98
* 基本思路:采用数学方法直接计算出矩阵元素P(x,y)的值.
* 将整个矩阵看成由一个一个的矩形圈组成,矩阵中某一矩形圈上任意一点P(x,y)的值=
* 位于外圈的所有点数+本圈处于点p(x,y)前面的所有点数+1
*/
public class Martrix { private int H; private int L; public static void main(String argv[]) { int h = Integer.parseInt(argv[0]); int w = Integer.parseInt(argv[1]); Martrix m1=new Martrix(h,w); m1.print(); } public Martrix() { this.H=3; this.L=3; } public Martrix(int x,int y) { this.H=x; this.L=y; } //计算点p(x,y)的值 public int getDotCount(int x,int y) { return getDotCount1(H,L,x,y) + getDotCount2(H,L,x,y) + 1; } //计算点P(x,y)外围矩形圈数 public static int getN(int H,int L,int x,int y) { return Math.min(Math.min(x,y),Math.min((H-x),(L-y))); } //计算点P(x,y)外围矩形圈上的点数 (等差数列,这个等差数列的公差为-8) public static int getDotCount1(int H,int L,int x,int y) { int N=getN(H,L,x,y);//等差数列的项数 int S1=2*(H+L); //等差数列的第一项,即最外围矩形上的点数 int S2=2*(H+L)-8*N + 8;//等差数列的第N项,即最后一圈矩形上的点数 return (S1+S2)/2 * N; //返回等差数列的和 } //计算与点P(x,y)处于同一个矩形圈上,且在点P前面的所有点数 (分段函数) public static int getDotCount2(int H,int L,int x,int y) { int N=getN(H,L,x,y); int x1=x-N; int y1=y-N; int H1=H-2*N; int L1=L-2*N; int count; if(L1==0) //特列:H >=L ,L为奇数,y=(L-1)/2 实例(H=6,L=5,x=3,y=3) return x1 ; if(H1==0) //特列: H < L ,H为奇数,x=(H-1)/2 实例(H=5,L=6,x=3,y=3) return y1; if(y1==0) //一般情况: { count=x1; } else if(x1==H1) //一般情况: { count=H1 + y1; } else if(y1==L1) //一般情况: { count=H1 + L1 + (H1 - x1); } else if(x1==0) //一般情况: { count=H1 + L1 + (H1 - x1) + (L1 - y1); } else //出错情况: { count= -1; } return count; } //计算并输出螺旋矩阵 public void print() { System.out.println("H = " + H +" , " + "L = " + L); System.out.println("******************************************"); for(int j=0;j<=L;j++) { for(int i=0;i<=H;i++) { System.out.print(getDotCount(i,j)+"\t"); } System.out.println(); } System.out.println("************************************"); } } 一次运行图: D:\java>java Martrix 8 9
H = 8 , L = 9
******************************************
1 2 3 4 5 6 7 8 9
34 35 36 37 38 39 40 41 10
33 60 61 62 63 64 65 42 11
32 59 78 79 80 81 66 43 12
31 58 77 88 89 82 67 44 13
30 57 76 87 90 83 68 45 14
29 56 75 86 85 84 69 46 15
28 55 74 73 72 71 70 47 16
27 54 53 52 51 50 49 48 17
26 25 24 23 22 21 20 19 18
************************************
阅读(439) | 评论(0) | 转发(0) |
0

上一篇:跳跃表

下一篇:水木大牛的驳壳

给主人留下些什么吧!~~