資料結構-稀疏矩陣(壓縮儲存,轉置,加法,乘法)類庫
阿新 • • 發佈:2019-01-29
上完資料結構課,練練手~
個人能力問題,可能會有少許bug,畢竟本人debug這個程式碼用了2天的空閒時間...
目前本人測試沒有問題...記錄一下,方便以後整理,更新程式碼, debug。
-----------------
程式碼用了兩個class分別封裝Matrix和record,record為壓縮矩陣的記錄,記錄了一個元素的位置以及資料內容。Matrix則記錄矩陣的資料(record封裝),大小,以及轉置要用到的cpot陣列,也就是記錄從第一列到第n列,共有多少個元素。
程式碼中cpot由0開始,方便書寫程式碼。而資料結構書中(清華大學那本)是以1開頭的,大家要用的話也可以注意一下。
程式碼裡也含有大量debug輸出語句,要檢視資料可以呼叫輸出函式或去除註釋。
#include <iostream> using namespace std; typedef int ET; class record { public: record() { this->posx = 0; this->posy = 0; this->data = 0; } record(int posx, int posy, ET data) { this->posx = posx; this->posy = posy; this->data = data; } int get_x() { return posx; } int get_y() { return posy; } ET get_data() { return data; } void edit_x(int x) { this->posx = x; } void edit_data(ET data) { this->data = data; } void edit_y(int y) { this->posy = y; } private: int posx; int posy; ET data; }; class Matrix { public: int tmp_input; Matrix() { int x, y; cout << "Input \"x and y\" size in Matrix : "; cin >> x >> y; this->store_x(x); this->store_y(y); this->set_size_malloc(x*y); this->init_num_array(x*y); } Matrix(int x, int y) { this->store_x(x); this->store_y(y); this->set_size_malloc(x*y); this->init_num_array(x*y); } void init_num_array(int _size) { this->cpot = new int[y_size]; //(int*)malloc(y_size* sizeof(int)); } void set_size_malloc(int _size) { this->point = 0; this->mat_size = _size; this->r = new record[_size]; //(record*)malloc(sizeof(record)*_size); } void store_x(int x) { this->x_size = x; } void store_y(int y) { this->y_size = y; } int get_x() { return this->x_size; } int get_y() { return this->y_size; } record* get_record() { return this->r; } void store_record(record record_piece) { r[point] = record_piece; } int get_point() { return this->point; } void edit_point(int point) { this->point = point; } void input() { //memset(num, 0, y_size * sizeof(int)); for (int j = 0; j < x_size; j++) for (int k = 0; k < y_size; k++) { cin >> tmp_input; if (tmp_input != 0) { this->store_record(record(j, k, tmp_input)); ++point; } else { continue; } } //calc cpot(num first) //cout << "Output num[]:" << endl; //for (int i = 0; i < y_size; ++i) //{ // cout << num[i] << " "; //} cout << endl; calc_cpot(); //output_cpot(); } int* calc_num() { int *num = new int[mat_size] {0}; for (int p = 0; p < point; ++p) { int y = r[p].get_y(); num[y]++; } return num; } void calc_cpot() { /*calc cpot(num first) -> calc cpot */ int *num = calc_num(); cpot[0] = 0; for (int i = 1; i < y_size; ++i) { cpot[i] = num[i - 1] + cpot[i - 1]; //*(cpot + i * sizeof(int)) = num[i-1] + *(cpot + (i-1) * sizeof(int)); } delete(num); } void output_record() { cout << endl<< "Output record:" << endl << "X-------Y-------Data" << endl; for (int i = 0; i < point; ++i) { record* o_r = &r[i]; cout << o_r->get_x() << " " << o_r->get_y() << " " << o_r->get_data() << endl; } cout << endl << "========Output record End=========" << endl; } void output_cpot() { cout << "Output cpot(-1):" << endl; for (int i = 0; i < y_size; ++i) { cout << this->cpot[i] << " "; } cout << endl; } Matrix transpose() { Matrix T=Matrix(get_y(),get_x()); //cout << endl << "========Transpose Start=========" << endl; T.edit_point(this->point); //convert pos //this->output_cpot(); for (int p = 0; p < point; ++p) { int col = r[p].get_y(); //(r+ sizeof(record) * p)->get_y(); int convert_col = this->cpot[col]; //*(cpot+ col * sizeof(int)); record* m2 = &T.get_record()[convert_col]; //(mat2.get_record()+((sizeof(record))*convert_col)); m2->edit_x(col); m2->edit_y(r[p].get_x() //(r+ sizeof(record) * p)->get_x() ); m2->edit_data(r[p].get_data() //(r+ sizeof(record) * p)->get_data() ); this->cpot[col] = this->cpot[col] + 1; //*(cpot+ col*sizeof(int))=*(cpot+ col*sizeof(int))+1; } T.calc_cpot(); //mat2.output_cpot(); this->calc_cpot(); //mat2.output_record(); //cout << endl << "========Transpose End=========" << endl; return T; } Matrix multiply(Matrix mat2) { //judge if can be multiplied if(this->get_x()==mat2.get_y() && this->get_y()==mat2.get_x()) { Matrix T= Matrix(get_x(),mat2.get_y()); //point int value[this->get_x()][mat2.get_y()]; memset(value,0, sizeof(value)); for (int j=0;j<point;++j) { for(int k=0;k<mat2.get_point();++k){ if(r[j].get_y()!=mat2.get_record()[k].get_x()) continue; //debug mode //cout<<"value["<<r[j].get_x()<<"]["<<mat2.get_record()[k].get_y()<<"]+=Mat1(" // <<r[j].get_x()<<","<<r[j].get_y()<<") *"<<" Mat2(" // <<mat2.get_record()[k].get_x()<<","<<mat2.get_record()[k].get_y()<<") \'s Data."<<endl; //cout<<"data1:"<<r[j].get_data()<<" data2:"<<mat2.get_record()[k].get_data()<<endl<<endl; // value[r[j].get_x()][mat2.get_record()[k].get_y()]+= r[j].get_data() * mat2.get_record()[k].get_data(); } } for (int j=0;j<this->get_x();++j){ for(int k=0;k<mat2.get_y();++k){ if(value[j][k]!=0){ //debug mode //cout<<value[j][k]<<" "; // T.store_record(record(j,k,value[j][k])); T.edit_point(T.get_point()+1); } else continue; } } return T; } else { cout<<"It's cannot be multiplied by the Matrix you input."<<endl; return {0,0}; } } Matrix add(Matrix mat2) { //judge if can be added if(this->get_x()==mat2.get_x() && this->get_y()==mat2.get_y()) { Matrix T= Matrix(get_x(),mat2.get_y()); //point int value[this->get_x()][mat2.get_y()]; memset(value,0,sizeof(value)); for (int j=0;j<point;++j) { for(int k=0;k<mat2.get_point();++k){ if(r[j].get_x()!=mat2.get_record()[k].get_x() || r[j].get_y()!=mat2.get_record()[k].get_y()) continue; //debug mode //cout<<"value["<<r[j].get_x()<<"]["<<mat2.get_record()[k].get_y()<<"]+=Mat1(" // <<r[j].get_x()<<","<<r[j].get_y()<<") *"<<" Mat2(" // <<mat2.get_record()[k].get_x()<<","<<mat2.get_record()[k].get_y()<<") \'s Data."<<endl; //cout<<"data1:"<<r[j].get_data()<<" data2:"<<mat2.get_record()[k].get_data()<<endl<<endl; // value[r[j].get_x()][mat2.get_record()[k].get_y()]= r[j].get_data() + mat2.get_record()[k].get_data(); } } for (int j=0;j<this->get_x();++j){ for(int k=0;k<mat2.get_y();++k){ if(value[j][k]!=0){ //debug mode //cout<<value[j][k]<<" "; // T.store_record(record(j,k,value[j][k])); T.edit_point(T.get_point()+1); } else continue; } } return T; } else { cout<<"It's cannot be added by the Matrix you input."<<endl; return {0,0}; } } void show(){ int tmp_point=0; for(int j=0;j<get_x();++j){ for(int k=0;k<get_y();++k){ if(r[tmp_point].get_x()==j && r[tmp_point].get_y()==k){ cout<<r[tmp_point].get_data()<<" "; ++tmp_point; } else cout<<"0 "; } cout<<endl; } } private: int x_size; int y_size; int mat_size; int *cpot; int point; record* r; }; int main() { Matrix mat1 = Matrix(); mat1.input(); Matrix mat2 = mat1.transpose(); Matrix mat3=mat2.transpose(); //mat.output_record(); //mat.output_cpot(); cout << "This is mat1(User's Input)" << endl; mat1.show(); cout << "This is mat2(transpose mat1):" << endl; mat2.show(); cout << "This is mat3(transpose mat2)" << endl; mat3.show(); cout << "This is mat4(mat1 * mat2)" << endl; Matrix mat4=mat1.multiply(mat2); mat4.show(); cout << "This is mat5(mat1 + mat3)" << endl; Matrix mat5=mat1.add(mat3); mat5.show(); return 0; } /* 測試資料: ========test1====== 6 7 0 12 9 0 0 0 0 0 0 0 0 0 0 0 -3 0 0 0 0 14 0 0 0 24 0 0 0 0 0 18 0 0 0 0 0 15 0 0 -7 0 0 0 =================== ===========test2===== 3 3 5 6 7 8 9 1 0 0 0 ======================== */