您的位置:首页 > 职场人生

顺时针打印出矩阵(面试编程或者上机题)

2014-02-16 22:05 591 查看
题目:输入一个矩阵,按照从外向里以顺时针顺序依次打印出每一个数字,例如:如果输入如下矩阵:

1 2 3 4

5 6 7 8

9 10 11 12

13 14 15 16

则依次打印出数字1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10。

两年之前,去方正面试的时候,上机让做此道题,想了好久没有想出来,悔恨做了1个小时的笔试卷子.....

今天想把这个经典的面试题搞明白:

思路:

按照题目描述,转圈打印,一圈以从左向右,从上到下,从右向左,从下到上。

如上例子:

1、2、3、4、8、12、16、15、14、13、9、5为第一圈

6、7、11、10为第二圈

这个题目的难点是如何判定多个边界条件。

分析这个循环结束的条件。对一个5×5的矩阵而言,最后一圈只有一个数字,对应的坐标为(2, 2)。我们发现5 > 2 * 2。对一个6×6的矩阵而言,最后一圈有四个数字,对应的坐标仍然为(2,
2)。我们发现6 > 2 * 2依然成立。于是我们可以得出,让循环继续的条件是columns > startX * 2 && rows > startY * 2。

递归代码实现:

#include <iostream>

using namespace std;

/*
方法一:递归方式;顺时针循环打印,一圈一圈的打印,先右,再下,再左,再上;打完一圈再打内圈,当不符合条件时,结束。
参数:numbers:二维矩阵;columns:矩阵的列数;rows:矩阵的行数;start:一圈开始的左上角的坐标值(x、y坐标是相同的,例如5X5,第一圈左上角(start,start)即为(0,0)...)
*/
void PrintMatrix(int **number, int columns, int rows, int start=0)
{
if( !number || columns < 1 || rows < 1 || start < 0 )
return;
if( columns <= 2*start || rows <= 2*start )
return;

int stopX = columns - 1 - start;//一圈最右列在坐标中的位置
int stopY = rows - 1 - start;//一圈最大行在坐标中位置

//打印此圈中的最上行
for( int i=start; i<=stopX; i++)
cout <<number[start][i]<<" ";
//打印此圈中的最右列
if(start < stopX) //如果此圈中不止有一列
for(int i=start+1; i<=stopY; i++)
cout<<number[i][stopX]<<" ";
//打印次圈中的最下行
if(start < stopX && start < stopY)
for(int i=stopX-1; i >= start; i--)
cout<<number[stopY][i]<<" ";
//打印次圈中的最左行
if(start < stopX && start < stopY - 1)
for(int i=stopY-1; i >= start+1; i--)
cout<<number[i][start]<<" ";
PrintMatrix(number, columns, rows, start+1);//下一圈循环
}
void Test(int columns, int rows)
{
cout<<"Test Begin:"<<columns<<" columns,"<<rows<<" rows."<<endl;
if(columns < 1 || rows < 1)
return;

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;
}

}

PrintMatrix(numbers, columns, rows);
cout<<endl;
for(int i = 0; i < rows; ++i)
delete[] (int*)numbers[i];
delete[] numbers;
}
int main()
{
Test(1,1);
Test(2,2);
Test(4,5);
Test(5,5);
return 0;
}


非递归的形式,可以参见《剑指offer》http://blog.csdn.net/rsljdkt/article/details/9749915
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: