顺时针打印矩阵

输入一个M*N矩阵,按照从外向里以顺时针的顺序依次为1,2,3,4,5,6,...........M*N。

如:4*4矩阵

1    2    3    4

12  13  14  5

11  16  15  6

10  9    8    7

思路:从四个方向上依次遍历,关键是判断哪些位置是已经存放的,哪些是还未放的,这里用0表示该处是空的,非0表示已经存放过。四个方向依次是: 向左(y++){0, 1}, 向下(x++){1,0}, 向右(y--){0, -1}, 向上(x--){-1, 0}。

#include <iostream>

using namespace std;

template<int R, int C>
class SpinMatrix
{
private:
	int m_matrix[R][C];

	struct Offset
	{
		int dx;
		int dy;
	};

	bool valid(int x, int y);

public:
	SpinMatrix();
	void run();
	void println();
	int rows();
	int columns();
};

template<int R, int C>
SpinMatrix<R, C>::SpinMatrix()
{
	for(int i=0; i < R; i++)
	{
		for(int j=0; j < C; j++)
		{
			m_matrix[i][j] = 0;
		}
	}
}

/*判断矩阵元素位置是有是有效位置*/
template<int R, int C>
bool SpinMatrix<R, C>::valid(int x, int y)
{
	bool ret = true;

	ret = ret && ( (0 <= x) && (x < R) ); //是否越界
	ret = ret && ( (0 <= y) && (y < C) );
	ret = ret && ( m_matrix[x][y] == 0 ); //是否元素位置已被占用

	return ret;
}

template<int R, int C>
void SpinMatrix<R, C>::run()
{
	/*四个方向,向左(y++),向下(x++),向右(y--),向上(x--)*/
	const Offset OFFSET[] = { {0, 1}, {1, 0}, {0, -1}, {-1, 0}};
	const int OSLEN = sizeof(OFFSET) / sizeof(Offset);

	int cx = 0;
	int cy = 0;
	int cd = 0;
	int i = 1;  //要放的值

	do
	{
		m_matrix[cx][cy] = i;

		/*如果元素位置是无效的,包括元素位置越界和访问已占用位置*/
		if( !valid( cx + OFFSET[cd].dx, cy + OFFSET[cd].dy) )
		{
			cd = (cd + 1) % OSLEN; //转向
		}

		cx += OFFSET[cd].dx;
		cy += OFFSET[cd].dy;

		i++;
	}while( i <= R*C );
}

template<int R, int C>
void SpinMatrix<R, C>::println()
{
	for(int i=0; i < R; i++)
	{
		for(int j=0; j < C; j++)
		{
			cout<<m_matrix[i][j]<<'\t';
		}

		cout<<endl;
	}

	cout<<endl;
}

template<int R, int C>
int SpinMatrix<R, C>::rows()
{
	return R;
}

template<int R, int C>
int SpinMatrix<R, C>::columns()
{
	return C;
}

int main()
{
	SpinMatrix<5, 4> sm1;
	SpinMatrix<4, 3> sm2;

	cout<<sm1.rows()<<" * "<<sm1.columns()<<endl;
	sm1.run();
	sm1.println();

	cout<<sm2.rows()<<" * "<<sm2.columns()<<endl;
	sm2.run();
	sm2.println();

	return 0;
}


 

 

你可能感兴趣的:(顺时针打印矩阵)