稀疏数组 C++练习
韩顺平老师数据结构与算法 P7-P9
007_尚硅谷_稀疏数组的应用场景_哔哩哔哩_bilibili




/* 尚硅谷-韩顺平-数据结构与算法.cpp : Defines the entry point for the console application. BV1E4411H73v */ using namespace std; #include <iostream> #include <vector> #include <map> #include <fstream> //SparsItem为步骤相应的行,列,值数据 class SparsItem{ public: int s_row; int s_col; int s_val; SparsItem(){ } SparsItem(int row, int col, int val){ this->s_row = row; this->s_col = col; this->s_val = val; } }; //map<pair(int, SparsItem)> m_sitem; class MyArray{ public: //建立一个MAP用于存放具体的稀疏数组的行数据,int为步骤数,SparsItem为步骤相应的行,列,值数据 //map中存放的数据格式为 map<make_pair(步骤数int, SparsItem{行数int, 列数int, 值int})> map<int, SparsItem> m_sitem; int maxrow = 11; int maxcol = 11; //用于记录稀疏数组有多少个值,也就是五子棋中走了多少步 int steps = 0; //获取数组的首地址,行数和列数,传入的行数和列数进行遍历,实现通用性 void convertToSpars(int *a, int maxrow = 11, int maxcol = 11, int defaultval = 0){ //清空稀疏数组内容 this->m_sitem.clear(); //外部传入这个二维数组的行列,默认为11 this->maxrow = maxrow; this->maxcol = maxcol; this->steps = 0; //依次遍历数组中所有的元素,当元素不与默认值相同,则进行m_sitem内容的添加 for (int i = 0; i < this->maxrow; i++){ for (int j = 0; j < this->maxcol; j++){ if (a[i * this->maxcol + j] != defaultval){ m_sitem.insert(make_pair(++(this->steps), SparsItem(i, j, a[i * this->maxcol + j]))); } } } //测试打印map中的内容 cout << "测试打印map中的内容" << endl; for (map<int, SparsItem>::iterator it = this->m_sitem.begin(); it != this->m_sitem.end();it++){ cout << "步骤号是: " << (*it).first << " 行,列,值: " << (*it).second.s_row << " " << (*it).second.s_col << " " << (*it).second.s_val << endl; } this->saveSparsToFile(); } void saveSparsToFile(){ //创建文件对象,如果打开失败则直接返回 ofstream ofs; ofs.open("spartfile.txt", ios::out); if (!ofs.is_open()){ cout << "spartfile.txt打开失败" << endl; return; } //首先写入首行内容,编号固定为0, 内容为总行数,总列数,有效数据数量 ofs << 0 << " "; ofs << this->maxrow << " "; ofs << this->maxcol << " "; ofs << this->steps << endl; //通过for循环依次写入每一步的内容 for (int i = 1; i < this->steps + 1; i++){ ofs << i << " "; ofs << this->m_sitem[i].s_row << " "; ofs << this->m_sitem[i].s_col << " "; ofs << this->m_sitem[i].s_val << endl; } //关闭文件对象 ofs.close(); } //从文件中读取稀疏数组并转换为普通二维数组,可以指定默认值,不指定则普通数组默认值为0 void readFromFile(int defaltval = 0){ //以读取方式打开文件spartfile.txt ifstream ifs; ifs.open("spartfile.txt", ios::in); if (!ifs.is_open()){ cout << "spartfile.txt打开失败" << endl; return; } //二维数组由二维vector来实现,比较容易 vector <vector<int>> v; //读取第一行内容,第一行为稀疏数组的元数据 int totalsteps; ifs >> this->steps; ifs >> this->maxrow; ifs >> this->maxcol; ifs >> totalsteps; //cout << "this->maxrow " << this->maxrow << " this->maxcol " << this->maxcol << endl; //cout << "ifs >> this->steps " << this->steps << endl; //for循环总行数,每次循环创建一个vector容器,尺寸为maxcol个元素,初始值为传入的参数,默认值为0 for (int i = 0; i < this->maxrow; i++){ v.push_back(vector<int>(this->maxcol, defaltval)); } //测试打印刚创建的二维vector cout << "测试打印刚创建的二维vector" << endl; for (int i = 0; i < this->maxrow; i++){ for (int j = 0; j < this->maxcol; j++){ cout << v[i][j] << "\t"; } cout << endl; } cout << "--------------------------" << endl; //清空map容器 this->m_sitem.clear(); int step; int row; int col; int val; //循环读取文件中的内容,由于之前已经读取过一行元数据,实际这个循环是从第二行开始读取的 //每次循环做两件事情,第一个是向内部的map添加内容,第二是修改二维vector的相应内容 while (ifs >> step && ifs >> row && ifs >> col && ifs >> val){ this->m_sitem.insert(make_pair(step, SparsItem(row, col, val))); v[row][col] = val; } //关闭文件对象 ifs.close(); //打印从稀疏数组恢复的二维数组 cout << "打印从稀疏数组恢复的二维数组" << endl; for (int i = 0; i < this->maxrow; i++){ for (int j = 0; j < this->maxcol; j++){ cout << v[i][j] << "\t"; } cout << endl; } cout << "--------------------------" << endl; //测试打印map中的内容 cout << "测试打印map中的内容" << endl; for (map<int, SparsItem>::iterator it = this->m_sitem.begin(); it != this->m_sitem.end(); it++){ cout << "步骤号是: " << (*it).first << " 行,列,值: " << (*it).second.s_row << " " << (*it).second.s_col << " " << (*it).second.s_val << endl; } } }; void main(){ int dArray[11][11] = { { 0, 0, 0, 22, 0, 0, 15 }, { 0, 11, 0, 0, 0, 17, 0 }, { 0, 0, 0, -6, 0, 0, 0 }, { 0, 0, 0, 0, 0, 39, 0 }, { 91, 0, 0, 0, 0, 0, 0 }, { 0, 0, 28, 0, 0, 0, 0 }, }; //cout << "sizeof(dArray[0]) / sizeof(dArray[0][0]) = " << sizeof(dArray[0]) / sizeof(dArray[0][0]) << endl; //cout << "sizeof(dArray) / sizeof(dArray[0]) = " << sizeof(dArray) / sizeof(dArray[0]) << endl; MyArray m; /* 以一维数组的形式传进去 // sizeof(dArray) / sizeof(dArray[0])代表行数,数组总大小/数组每行的大小 sizeof(dArray[0]) / sizeof(dArray[0][0])代表列数,数组行大小/数组每个元素大小 */ //m.convertToSpars((int*)dArray, sizeof(dArray) / sizeof(dArray[0]), sizeof(dArray[0]) / sizeof(dArray[0][0])); int choice; while (true) { //测试打印原始二维数组 cout << "测试打印原始二维数组" << endl; for (int i = 0; i < 11; i++){ for (int j = 0; j < 11; j++){ cout << dArray[i][j] << "\t"; } cout << endl; } cout << "-------------------------------" << endl; cout << "测试功能" << endl; cout << "1. 测试从普通二维数组转为稀疏数组并保存文件" << endl; cout << "2. 测试从文件读出稀疏数组并还原成二维数组" << endl; cout << "3. 退出" << endl; cin >> choice; if (cin.fail()){ cin.clear(); cin.sync(); } switch (choice) { case 1: m.convertToSpars((int*)dArray, sizeof(dArray) / sizeof(dArray[0]), sizeof(dArray[0]) / sizeof(dArray[0][0]));; system("pause"); break; case 2: m.readFromFile(); system("pause"); break; case 3: return; default: break; } system("cls"); } }

浙公网安备 33010602011771号