九月鹰飞

慎独自修,忠恕宽容,至诚尽性。

  VC知识库BLOG :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 登录 ::
  19 随笔 :: 13 文章 :: 160 评论 :: 5 Trackbacks
<2004年12月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

留言簿(3)

随笔分类

随笔档案

文章分类

文章档案

相册

搜索

最新评论

阅读排行榜

评论排行榜

<PRE>

也谈螺旋矩阵的生成

===================================================================

问题描述:给出n,要求打印顺时针或者逆时针螺旋矩阵,例如:

n = 3:

1  8  7
2  9  6
3  4  5

n = 4:

1 12 11 10
2 13 16  9
3 14 15  8 
4  5  6  7

现在实现逆时针的螺旋矩阵。首先我们考虑填充的方向,开始从上到下,每次到达边界以后改变
方向(左转弯),假设Dir表示前进的方向,则有:

//Dir:
// 0: down; 1: right; 2: up; 3:left
void ChangeDirection( int& Dir)
{
 Dir ++;
 if(Dir>3)
  Dir = 0;
}

其次,边界是什么概念?当然首先是到达矩阵的边缘,或者是遇到矩阵里面已经有数据了,就必须
改变方向了(无需证明)。因此有下面的位置判别函数:

typedef struct tagPos
{
 int x;
 int y;
}POS;

//return 0 means Position not valid
//Data:  the metrics data
//n   :  the metrics dimension
int PosIsValid(int *Data, POS &p, int n)
{
 if( p.x<0 || p.x>=n )return 0;
 if( p.y<0 || p.y>=n )return 0;

 if( Data[ p.y*n + p.x ] != 0 )return 0;
 return 1;
}

有了以上两点,获取下一个填充位置就很方便了:
//Data : the Metrics
//p    : Current position
//Dir  : Filling direction
//n    : Dimension of the metircs
void GetNextPos(int *Data, POS &p , int& Dir, int n)
{
 POS next;
 
 for(;;)
 {
  //calculate the next position from p
  next.x = p.x;  next.y = p.y;
  switch(Dir)
  {
  case 0: //down
   next.y++;  break;
  case 1: //right
   next.x++;  break;
  case 2: //up
   next.y--;  break;
  case 3: //left
   next.x--;  break;
  }

  //determine whether the next position is valid
  if(!PosIsValid(Data, next, n))
  {
   //if the new position is not valid, that means
   //we must change the direction,and continue get
   //the new position
   ChangeDirection(Dir);
  }
  else break;
 }

 //change current position to new position
 p.x = next.x;
 p.y = next.y;
}

一切准备就绪,我们现在可以给出矩阵的填充函数了:

//Data : the Metrics
//n    : Metrics Dimension
//Dir  : Filling Operation Direction
void FillMatrics(int *Data, int n, int Dir)
{
 POS p;
 p.x = p.y = 0; //first position at point (0,0)

 for(int i=1; i<=n*n; i++)
 {
  int index = p.y * n + p.x; //calculate position
  Data[index] = i;
  if(i<n*n)
   GetNextPos(Data, p, Dir, n);
 }
}

写个主程序测试一下:

#include <stdio.h>

void main()
{
 int n;
 printf("\nPlease input the metrics dimension:");
 scanf("%d",&n);
 
 int *data = new int[n*n];

 //we must initialize the metrics with zero.
 for(int i=0;i<n*n; i++)data[i]=0;

 FillMatrics(data,n,0); 

 //print the result!
 printf("\nThe Result :\n");
 for( i=0;i<n;i++)
 {
  for(int j=0;j<n;j++)
  {
   printf("%d\t  ", data[i*n+j]);
  }
  printf("\n");
 }

 delete[] data;
}
//================================End=======================

//iwaswzq 2004/12/14

</PRE>

posted on 2004-12-14 23:28 九月鹰飞 阅读(4148) 评论(14)  编辑 收藏

评论

# re: 也谈螺旋矩阵的生成 2004-12-15 22:36 一笑
门是出了,撞了一头包,哈哈。
贴出我的,做个比较:P
http://blog.vckbase.com/smileonce/archive/2004/11/09/1395.aspx

# re: 也谈螺旋矩阵的生成 2005-01-12 06:03 Ninjai
#include <stdio.h>
#define M 12
#define N 14 // M*N 矩阵的输出
#define Down 0
#define Right 1
#define Up 2
#define Left 3

int a[M][N]={0};

void PrintMatrix(int *a,int m,int n)
{
int i,j;
for(i=0;i<m*n;i+=n)
{
for(j=0;j<n;j++)
printf("%4d ",a[i+j]);
printf("\n");
}
}

int Turn(int i,int j,int Dir)
{
if(Dir==Down&&((i+1)==M||a[i+1][j]!=0)) return Left;
if(Dir==Right&&((j+1)==N||a[i][j+1]!=0)) return Down;
if(Dir==Up&&((i-1)==-1||a[i-1][j]!=0)) return Right;
if(Dir==Left&&((j-1)==-1||a[i][j-1]!=0)) return Up;
return Dir;
}

main()
{
int i,j;
int count;
int dir;
count=1;
i=0;j=N-1;
dir=Down;

while(count<=M*N)
{
a[i][j]=count;
dir=Turn(i,j,dir);
switch(dir)
{
case Down:
i++;
break;
case Right:
j++;
break;
case Up:
i--;
break;
case Left:
j--;
break;
}
count++;
}
PrintMatrix(a,M,N);
getch();
}


标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]