MOOC清华《面向对象程序设计》第5章:OOP版填充数字旋转矩阵-产品级!-终极中文版!

最大的封装就是化于无形,最好的产品就是傻瓜产品!最终极的用户就是什么都不懂的用户!——连这种用户都能得心应手地使用我们的产品,我们的产品才算做到家了!代码如下:

//main.cpp
#include <iostream>
#include "Matrix.h"
using namespace std;

const int str_length = 7;//经测试,至少为7;印证了每个汉字占2个字节('\0'占一个字节) 

int main() {
	int size;
	char wise_or_anti[str_length];
	char first_point[str_length];
	cout << "请输入矩阵的边长 N: ";
	cin >> size;
	cout << "请输入“顺时针”或“逆时针”: ";
	cin >> wise_or_anti;
	cout << "请输入从哪一个角开始填充(左上角、左下角、右上角、右下角): ";
	cin >> first_point;
	
	Matrix obj(size);
	obj.fill_style(wise_or_anti, first_point);
	obj.fill();
	cout << obj;
	
	return 0;
}


//Matrix.h
#ifndef Matrix_h
#define Matrix_h

#include <iostream>
using namespace std;

class Matrix{
	int _size;//方阵的规模 
	int *_data;//数据空间
	int row, col;
	char dir;
	char* _wise_or_anti;
	char* _first_point;
	int findPosition_clockwise();//顺时针辅助函数
	int findPosition_anticlock();//逆时针辅助函数 
	
public:
	Matrix(int size);
	~Matrix();
	void fill();
	int fill_style(char* str1, char* str2);
	friend ostream& operator<< (ostream& out, const Matrix& m); 
};

#endif


//Matrix.cpp
#include <iostream>
#include <cstring>
#include "Matrix.h"
using namespace std;

Matrix::Matrix(int size): _size(size) {
//改变构造函数的初始化列表可以改变第一个数字的位置,注意不要把size-1写成了size 
	_data = new int[size * size];
	memset(_data, 0, sizeof(int) * _size * _size);
}

Matrix::~Matrix(){
	delete _data;
}

ostream& operator<< (ostream& out, const Matrix& m){
	for(int r = 0; r < m._size; r++){ //row
		for(int c = 0; c < m._size; c++) //col
			cout << *(m._data + r * m._size + c) << '\t';
		cout << endl;
	}
}

int Matrix::fill_style(char* str1, char* str2){
	//strcpy(_wise_or_anti, str1);//fatal error!
	//strcpy(_first_point, str2);//fatal error!
	_wise_or_anti = str1;
	_first_point = str2;
	if(strcmp(str1, "顺时针") == 0){
		if(strcmp(str2, "左上角") == 0) return 1;
		if(strcmp(str2, "右上角") == 0) return 2;
		if(strcmp(str2, "右下角") == 0) return 3;
		if(strcmp(str2, "左下角") == 0) return 4;
	}
	if(strcmp(str1, "逆时针") == 0){
		if(strcmp(str2, "左上角") == 0) return 5;
		if(strcmp(str2, "左下角") == 0) return 6;
		if(strcmp(str2, "右下角") == 0) return 7;
		if(strcmp(str2, "右上角") == 0) return 8;
	}
}

void Matrix::fill(){
	int n = fill_style(_wise_or_anti, _first_point);
	if(n == 1){//顺时针、左上角 
		row = 0;
		col = -1;
		dir = 'R';
		for(int num = 1; num <= _size * _size; num++){
			int pos = findPosition_clockwise();
			_data[pos] = num;
		}
	}
	if(n == 2){//顺时针、右上角 
		row = -1;
		col = _size - 1;
		dir = 'D';
		for(int num = 1; num <= _size * _size; num++){
			int pos = findPosition_clockwise();
			_data[pos] = num;
		}
	}
	if(n == 3){//顺时针、右下角 
		row = _size - 1;
		col = _size;
		dir = 'L';
		for(int num = 1; num <= _size * _size; num++){
			int pos = findPosition_clockwise();
			_data[pos] = num;
		}
	}
	if(n == 4){//顺时针、左下角 
		row = _size;
		col = 0;
		dir = 'U';
		for(int num = 1; num <= _size * _size; num++){
			int pos = findPosition_clockwise();
			_data[pos] = num;
		}
	}
	if(n == 5){//逆时针、左上角 
		row = -1;
		col = 0;
		dir = 'D';
		for(int num = 1; num <= _size * _size; num++){
			int pos = findPosition_anticlock();
			_data[pos] = num;
		}
	}
	if(n == 6){//逆时针、左下角 
		row = _size - 1;
		col = -1;
		dir = 'R';
		for(int num = 1; num <= _size * _size; num++){
			int pos = findPosition_anticlock();
			_data[pos] = num;
		}
	}
	if(n == 7){//逆时针、右下角 
		row = _size;
		col = _size - 1;
		dir = 'U';
		for(int num = 1; num <= _size * _size; num++){
			int pos = findPosition_anticlock();
			_data[pos] = num;
		}
	}
	if(n == 8){//逆时针、右上角 
		row = 0;
		col = _size;
		dir = 'L';
		for(int num = 1; num <= _size * _size; num++){
			int pos = findPosition_anticlock();
			_data[pos] = num;
		}
	}
}

int Matrix::findPosition_clockwise(){ //clockwise为顺时针的意思 
	switch(dir){
		case 'D':
			if(row < _size - 1 && _data[(row + 1) * _size + col] == 0)
				row++;
			else{
				dir = 'L'; // next direction
				col--;
			}
			break;
		case 'L':
			if(col > 0 && _data[row * _size + col - 1] == 0)
				col--;
			else{
				dir = 'U'; // next direction
				row--;
			}
			break;
		case 'U':
			if(row > 0 && _data[(row - 1) * _size + col] == 0)
				row--;
			else{
				dir = 'R'; // next direction
				col++;
			}
			break;
		case 'R':
			if(col < _size - 1 && _data[row * _size + col + 1] == 0)
				col++;
			else{
				dir = 'D'; // next direction
				row++;
			}
			break;
	}
	return row * _size + col;
}

int Matrix::findPosition_anticlock(){ //anticlock为逆时针的意思 
	switch(dir){
		case 'D':
			if(row < _size - 1 && _data[(row + 1) * _size + col] == 0)
				row++;
			else{
				dir = 'R'; // next direction
				col++;
			}
			break;
		case 'R':
			if(col < _size - 1 && _data[row * _size + col + 1] == 0)
				col++;
			else{
				dir = 'U'; // next direction
				row--;
			}
			break;
		case 'U':
			if(row > 0 && _data[(row - 1) * _size + col] == 0)
				row--;
			else{
				dir = 'L'; // next direction
				col--;
			}
			break;
		case 'L':
			if(col > 0 && _data[row * _size + col - 1] == 0)
				col--;
			else{
				dir = 'D'; // next direction
				row++;
			}
			break;
	}
	return row * _size + col;
}

全方位无死角测试结果:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值