1. 程式人生 > >稀疏矩陣的實現(三元組儲存)C++

稀疏矩陣的實現(三元組儲存)C++

通過三元組儲存稀疏矩陣,壓縮儲存空間

/*
稀疏矩陣的實現
*/
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
//儲存域
const int MAX_N = 100;
class elem_node
{
public:
	int elem_row;//元素行號
	int elem_col;//元素列號
	int elem_value;//元素值
};

class Node
{
public:
	int total_row;//總行數
	int total_col;//總列數
	int total_num;//非0元素總數
	elem_node data[MAX_N];//非0元素陣列
};

class Matrix
{
public:
	Matrix(){}
	~Matrix(){}
	//構建稀疏矩陣三元組
	void CreateMat(string filename, int rows, int cols)
	{
		int i, j;
		int fdata;
		ifstream readFile;
		mat.total_num = 0;
		mat.total_col = cols;//總行數
		mat.total_row = rows;//總列數
		readFile.open(filename);
		//開啟錯誤
		if (readFile.bad() || readFile.fail())
		{
			exit(0);
		}
		//檔案正常開啟
		if (readFile.is_open())
		{
			for (i = 0; i < rows; i++)
			{
				for (j = 0; j < cols; j++)
				{
					readFile >> fdata;
					if (readFile.good() && fdata != 0)
					{
						mat.data[mat.total_num].elem_row = i;//元素行號
						mat.data[mat.total_num].elem_col = j;//元素列號
						mat.data[mat.total_num].elem_value = fdata;//元素之
						mat.total_num++;//儲存陣列下標+1
					}
				}
			}
		}
		readFile.close();
	}
	//指定位置賦值,若不存在,則插入
	bool Value(int elem, int i, int j)
	{
		if (i >= mat.total_row || j >= mat.total_col)
		{
			return false;
		}
		else
		{
			int k = 0, k1;
			//搜尋行號<3,5> <3,6> <3,7> <3,8> 查詢<3,6>
			while (k<mat.total_num&&i>mat.data[k].elem_row)
			{
				k++;
			}
			//行號相等時,搜尋列號
			while (k<mat.total_num&&i == mat.data[k].elem_row&&j>mat.data[k].elem_col)
			{
				k++;
			}
			//退出時行號和列號相等於給定值
			if (mat.data[k].elem_row == i&&mat.data[k].elem_col == j)
			{
				mat.data[k].elem_value = elem;
			}
			//退出時行號列號不都等於給定值
			else
			{
				//三元組中位於該位置後的元素都後移
				for (k1 = mat.total_num - 1; k1 >= k; k1--)
				{
					mat.data[k1 + 1].elem_row = mat.data[k1].elem_row;
					mat.data[k1 + 1].elem_col = mat.data[k1].elem_col;
					mat.data[k1 + 1].elem_value = mat.data[k1].elem_value;
				}
				//插入值
				mat.data[k].elem_row = i;
				mat.data[k].elem_col = j;
				mat.data[k].elem_value = elem;
				mat.total_num++;
			}
		}
		return true;
	}
	//查詢並輸出值
	bool Assign(int &res, int i, int j)
	{
		if (i > mat.total_row || j > mat.total_col)
		{
			res = 0;
			return false;
		}
		else
		{
			int k = 0;
			//查詢行
			while (k<mat.total_num&&i>mat.data[k].elem_row)
			{
				k++;
			}
			//行數匹配,查詢列
			while (k<mat.total_num&&i == mat.data[k].elem_row&&j>mat.data[k].elem_col)
			{
				k++;
			}
			//找到
			if (i == mat.data[k].elem_row&&j == mat.data[k].elem_col)
			{
				res = mat.data[k].elem_value;
				return true;
			}
			//否則
			else
			{
				res = 0;
				return false;
			}
		}
	}
	//輸出三元組
	void DispMat()
	{
		if (mat.total_num <= 0)
		{
			return;
		}
		else
		{
			int i;
			for (i = 0; i < mat.total_num; i++)
			{
				cout << "<" << mat.data[i].elem_row << "," << mat.data[i].elem_col << "," << mat.data[i].elem_value << ">" << endl;
			}
		}
	}

	//輸出三元組
	void DispMat(Node mat)
	{
		if (mat.total_num <= 0)
		{
			return;
		}
		else
		{
			int i;
			for (i = 0; i < mat.total_num; i++)
			{
				cout << "<" << mat.data[i].elem_row << "," << mat.data[i].elem_col << "," << mat.data[i].elem_value << ">" << endl;
			}
		}
	}
	//轉置矩陣
	Node TranMat()
	{
		Node tranMat;
		tranMat.total_col = 0;
		tranMat.total_row = 0;
		tranMat.total_num = 0;
		if (mat.total_num <= 0)
		{
			return tranMat;
		}
		else
		{
			int p = 0, i, c;
			tranMat.total_col = mat.total_col;
			tranMat.total_row = mat.total_row;
			tranMat.total_num = mat.total_num;
			for (i = 0; i < mat.total_row; i++)//遍歷所有行
			{
				for (c = 0; c < mat.total_num; c++)//對於行,遍歷所有三元組元素
				{
					if (i == mat.data[c].elem_row)//若三元組中存在行號與i相等的組,則轉置
					{
						tranMat.data[p].elem_row = mat.data[c].elem_col;
						tranMat.data[p].elem_col = mat.data[c].elem_row;
						tranMat.data[p].elem_value = mat.data[c].elem_value;
						p++;
					}
				}
			}
			return tranMat;
		}
	}
	//矩陣相加

	Node MatAdd(Node mat1, Node mat2)
	{
		Node mat;
		//迴圈變數初始化
		int i = 0, j = 0, k = 0;
		//三元組初始化
		mat.total_col = 0;
		mat.total_num = 0;
		mat.total_row = 0;
		//矩陣不可相加
		if (mat1.total_col != mat2.total_col || mat1.total_row != mat2.total_row)
		{
			return mat;
		}
		//課相加
		else
		{
			//總行列數賦值
			mat.total_row = mat1.total_row;
			mat.total_col = mat1.total_col;
			//遍歷三元組
			while (i < mat1.total_num&&j < mat2.total_num)
			{
				//兩個三元組中對應元素行座標相等
				if (mat1.data[i].elem_row == mat2.data[j].elem_row)
				{
					//對應列座標mat1小
					if (mat1.data[i].elem_col < mat2.data[j].elem_col)
					{
						//賦值
						mat.data[k].elem_row = mat1.data[i].elem_row;
						mat.data[k].elem_col = mat1.data[k].elem_col;
						mat.data[k].elem_value = mat1.data[i].elem_value;
						k++;
						i++;
					}
					//對應列座標mat1大
					else if (mat1.data[i].elem_col>mat2.data[j].elem_col)
					{
						//賦值
						mat.data[k].elem_row = mat2.data[j].elem_row;
						mat.data[k].elem_col = mat2.data[j].elem_col;
						mat.data[k].elem_value = mat2.data[k].elem_value;
						k++;
						j++;
					}
					//對應列座標也相等
					else
					{
						//求對應元素和
						int temp_value = mat1.data[i].elem_value + mat2.data[j].elem_value;
						//若和值不等於0則賦值
						if (temp_value != 0)
						{
							mat.data[k].elem_row = mat1.data[i].elem_row;
							mat.data[k].elem_col = mat1.data[i].elem_col;
							mat.data[k].elem_value = temp_value;
							k++;
						}
						i++;
						j++;
					}
				}
				//對應行座標mat1小
				else if (mat1.data[i].elem_row < mat2.data[j].elem_row)
				{
					//賦值
					mat.data[k].elem_row = mat1.data[i].elem_row;
					mat.data[k].elem_col = mat1.data[i].elem_col;
					mat.data[k].elem_value = mat1.data[i].elem_value;
					k++;
					j++;
				}
				//對應行座標mat1大
				else
				{
					//賦值
					mat.data[k].elem_row = mat2.data[j].elem_row;
					mat.data[k].elem_col = mat2.data[j].elem_col;
					mat.data[k].elem_value = mat2.data[j].elem_value;
					k++;
					j++;
				}
			}
			//總元素個數
			mat.total_num = k;
			return mat;
		}
	}
	//獲取矩陣首地址
	Node &get_address()
	{
		return mat;
	}
private:
	Node mat;
};

//三元組操作
class operation
{
public:
	operation()
	{
		m_mat.CreateMat("data",6,7);
	}
	~operation(){}
	//輸出
	void display()
	{
		cout << "Output" << endl;
		m_mat.DispMat();
	}
	//矩陣轉置
	void trange()
	{
		cout << "Change" << endl;
		m_mat.DispMat(m_mat.TranMat());
	}
	//查詢
	void is_fond()
	{
		cout << "Fond Value" << endl;
		int res;
		m_mat.Assign(res, 2, 0);
		cout << res << endl;
	}
	//賦值
	void give_value()
	{
		cout << "Give New Value" << endl;
		m_mat.Value(18, 3, 4);
		m_mat.DispMat();
	}
	//矩陣相加
	void MatAdd()
	{
		cout << "Matrix Add" << endl;
		Matrix m_mat2;
		m_mat2.CreateMat("data1", 6, 7);
		m_mat.DispMat(m_mat.MatAdd(m_mat.get_address(), m_mat2.get_address()));
	}
private:
	Matrix m_mat;
};
int main()
{
	operation m_opr;
	m_opr.display();//輸出
	m_opr.give_value();//賦值
	m_opr.is_fond();//查詢
	m_opr.trange();//轉置
	m_opr.MatAdd();
	return 0;
}
測試結果