【C/C++练习题】顺时针打印矩阵

《剑指Offer》面试题29:顺时针打印矩阵


1 题目

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

 

2 问题分析

<1>首先理解问题,借用图形将问题抽象化为具体。

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

<2>如果把顺时针打印矩阵想象成打印一个又一个的圈,可以利用循环的方法来实现。分析循环开始和循环结束的条件

每次打印一个圈,起点位置的坐标值相等,即 startX = startY。并且满足

columns >= startX*2) && (rows >= startY*2)

<3>在具体分析实现打印一个圈,又需要哪些步骤,要不要考虑边界条件。其中,由于最后一个圈的矩阵会发生退化,要确定每一步的执行条件。

PS:拿到问题,先至上向下分析问题,在从下向上解决问题。

 

3 代码

#include "iostream"
#include "cstdlib"

using namespace std;

//问题:顺时针打印矩阵


bool Print_array_clockwise(int** numbers, int columns, int rows);
void Print_array_circle(int** numbers, int columns, int rows, int start);

//功能:顺时针方式打印数组
//输入:numbers矩阵首地址, columns 列数, rows 行数
//输出:false 参数无效, true 成功
bool Print_array_clockwise(int** numbers, int columns, int rows)
{
	//1.检查参数的有效性
	if ( (numbers == nullptr) || (columns <= 0) || (rows <= 0) )
	{
		return false;
	}

	int start = 0;		//定义起点(start, start)
	//2.循环方式顺时针打印矩阵,每次循环打印一圈
	while ( (columns >= start*2) && (rows >= start*2) )
	{
		Print_array_circle(numbers, columns, rows, start);	//打印一圈
		start++;
	}

	return true;

}

//打印一圈元素,分成四个步骤。由于打印到最后一个矩阵的时候,矩阵会退化(这时候不确定要分成几步),所以要明确每一步的执行条件
void Print_array_circle(int** numbers, int columns, int rows, int start)
{
	int endX = columns - 1 - start;	//终点列坐标
	int endY = rows - 1 - start;	//终点行坐标

	//1.从左向右打印列元素
	if (start <= endX)
	{
		for (int i = start;i <= endX;i++)
		{
			cout << numbers[start][i] << ",";
		}
	}

	//2.从上往下打印行元素
	if (start < endY)
	{
		for (int i = start+1;i <= endY;i++)
		{
			cout << numbers[i][endX] << ",";
		}
	}

	//3.从右向左打印列元素
	if ( (start < endX) && (start < endY) )
	{
		for (int i = endX-1;i >= start;i--)
		{
			cout << numbers[endY][i] << ",";
		}
	}

	//4.从下向上打印行元素
	if ( (start < endX) && (start+1 < endY) )
	{
		for (int i = endY-1; i >= start+1;i--)
		{
			cout << numbers[i][start] << ",";
		}
	}
}


void Test(int columns, int rows)
{

    int** numbers = new int*[rows];
    for(int i = 0; i < rows; ++i)
    {
        numbers[i] = new int[columns];
        for(int j = 0; j < columns; ++j)
        {
            numbers[i][j] = i * columns + j + 1;
        }
    }

	Print_array_clockwise(numbers, columns, rows);

	cout << endl;

}



int main(int argc, char const *argv[])
{
	Test(3, 3);	//3行3列

	Test(1, 5);	//5行1列

	Test(5, 1);	//1行5列


	return 0;
}

 

4 运行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hinzer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值