顺时针打印矩阵

题目:输入一个矩阵,rows行,columns列,按顺时针方向从外向里一次打印每一个数字。

分析:首先整体分析循环:第一个环的起点是(0,0),第二个环的起点是(1,1)……,依次得出每个环的起点都是行号和列号相等的点,表示为(start,start)。如果一个环的起点start<rows/2 && start<columns/2,那么就可以继续循环;

然后具体分析每个环的打印情况:对每个环,总是要执行从左到右的打印;如果起点start小于该环的行终结号,则需要打印从上到下的列;如果起点start小于该环的行终结号,并且起点start小于该环的列终结号,则需要打印从右向左的行;如果起点start该环的列终结号,并且小于该环的行终结号-1,则需要打印从下向上的列。

下面是具体代码实现:

#include <iostream>
using namespace std;

void Circle(int **data,int rows,int columns);
void PrintMatrix(int **data,int rows,int columns,int start);

int main()
{
 int data[4][4]={
  {1,2,3,4},
  {5,6,7,8},
  {9,10,11,12},
  {13,14,15,16}
 };

 Circle((int **)data,4,4);
 cout <<endl;
 return 0;
}

//整体规划打印环的执行
void Circle(int **data,int rows,int columns)
{
 if (data==NULL || rows<=0 || columns<=0)
  return;

 int start=0;
 while(rows > start*2 && columns > start*2)
 {
  PrintMatrix((int **)data,rows,columns,start);
  start++;
 }
}

//具体分析每个环内的打印次序
void PrintMatrix(int **data,int rows,int columns,int start)
{
 //只定义一个起点start是因为每个环的起点都是(start,start)

 int endx=columns-1-start;
 int endy=rows-1-start;

 //从左到右打印该环的第一行
 for (int i=start;i<=endx;i++)
 {
  //cout <<data[start][i] <<" ";
  //cout <<*(data+start*columns+i) <<" ";
  printf("%d  ",*(data+start*columns+i));
  /*二维指针做形参,不能以二维数组的形式输出,所以第一种方式cout <<data[start][i] 是错误的,
  更不能以一维数组data[start*columns+i]的形式输出;
  二维指针默认的是地址的地址,所以第二种方式cout <<*(data+start*columns+i)取一个*结果为16进制的形式;
  因此,只能通过printf,用%d强制将16进制转换为10进制*/
 }

 //判断是否需要从上到下打印该列,需要打印的条件是该环的行数大于起点的行号
 if (endy > start)
 {
  for (i=start+1;i<=endy;i++)
  {
   //cout <<data[i][endx] <<" ";
   //cout <<*(data+i*columns+endx) <<" ";
   printf("%d  ",*(data+i*columns+endx));
  }
 }

 //判断是否需要从右到左打印该行,需要打印的条件是该环的列数大于起点的列号,行数大于起点的行号
 if (endx > start && endy > start)
 {
  for (i=endx-1;i>=start;i--)
  {
   //cout<<data[endy][i] <<" ";
   //cout <<*(data+endy*columns+i) <<" ";
   printf("%d  ",*(data+endy*columns+i));
  }
 }

 //判断是否需要从下到上打印该行,需要打印的条件是该环的列数大于起点的列号,行数大于起点的行号-1
 if (endy-1 > start && endx > start)
 {
  for (i=endy-1;i>start;i--)
  {
   //cout <<data[i][start] <<" ";
   //cout <<*(data+i*columns+start) <<" ";
   printf("%d  ",*(data+i*columns+start));
  }
 }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值