您的位置:首页 > 理论基础 > 数据结构算法

懒猫老师-数据结构-(19)稀疏矩阵的乘法(三元组乘法)

2020-07-31 15:26 549 查看

文章目录

介绍

矩阵的乘法

参考代码

#include <iostream>
using namespace std;

const int MAX = 100;
const int ERROR = 0;
const int OK = 1;

/* 稀疏矩阵---三元组 */
typedef struct Triple
{
int row;     // 行号
int column;  // 列号
double item; // 非零元素值
} Triple;

/* 稀疏矩阵类定义 */
class TripleMatrix
{
private:
Triple data[MAX]; // 非零元三元组
int Rows;    // 稀疏矩阵的总行数
int Columns; // 稀疏矩阵的总列数
int Nums;    // 稀疏矩阵中非零元的总数
public:
TripleMatrix()
{
Rows = 0;
Columns = 0;
Nums = 0;
}

TripleMatrix(int m, int n)
{
Rows = m;
Columns = n;
Nums = 0;
}

~TripleMatrix() {
}

/* 根据行号列号, 读取矩阵元素值 */
double getItem(int m, int n)
{
if (m > Rows || n > Columns)
{
return ERROR; // 超过范围直接返回0
}

for (int i = 0; i < Nums; i++)
{   // 查找到行列号匹配的三元组, 返回非零值
if (data[i].row == m && data[i].column == n)
{
return data[i].item;
}
}
return 0; // 查找不到, 说明该元素为0
}

/* 根据行号, 列号和非零元, 向三元组中存入稀疏矩阵的一个元素 */
bool setItem(int m, int n, double item)
{
if (m > Rows || n > Columns) // 超过范围, 返回ERROR
{
return ERROR;
}
if (Nums == MAX) // 已存元素个数超过三元组可以存储的最大范围
{
return ERROR;
}
if (item == 0)   // 输入的数组元素值为0, 无需插入, 直接返回
{
return OK;
}

// 查找合适的存储位置
int index = 0;
while (index < Nums)
{
// 如果要找的row和col, 比已有三元组中的行列值大, 则继续向后移动
if (m > data[index].row)
{
index++;
}
else if (m == data[index].row && n > data[index].column) {
index++;
}
else
{
break;
}
}

if ((m == data[index].row) && (n == data[index].column))
{
data[index].item = item; // 替换
}
else
{
// index的后续元素都移动一个单元, 腾出index的位置 (插入)
for (int i = Nums; i > index; i--)
{
data[i] = data[i - 1];
}
data[index].row = m;
data[index].column = n;
data[index].item = item;

Nums++;
}
return OK;
}

/* 打印稀疏矩阵 */
void printMatrix()
{
cout << "打印稀疏矩阵如下: " << endl;
int index = 0;
for (int i = 1; i <= Rows; i++) // 注意这里要从1开始                      (关键)
{
for (int j = 1; j <= Columns; j++)
{
// 如果发现行列号匹配的三元组,则输出非零值
if (data[index].row == i && data[index].column == j)
{
cout << data[index].item << "\t";
index++;
}
else
{
cout << "O\t";
}
}
cout << endl;
}
cout << "矩阵共有" << Rows << "行" << Columns << "列, 共有" << Nums << "个非零元素" << endl;
}

/* 打印三元组数组 */
void printTriple()
{
cout << "三元组数组如下: " << endl;
cout << "row \tcolumn \titem" << endl;
for (int i = 0; i < Nums; i++)
{
cout << data[i].row << "\t" << data[i].column << "\t" << data[i].item << endl;
}
cout << endl; //------------------------------------------------------------------------------------
}

/* 稀疏矩阵的加法 */
friend bool addMatrix(TripleMatrix a, TripleMatrix b, TripleMatrix& sum)
{
if (a.Rows == b.Rows && a.Columns == b.Columns)
{
// 初始化result的行列值
sum.Rows = a.Rows;
sum.Columns = a.Columns;

for (int i = 1; i <= sum.Rows; i++)
{
for (int j = 1; j <= sum.Columns; j++)
{
double item = a.getItem(i, j) + b.getItem(i, j);
// 如果计算出来的结果不为0, 则插入到三元组中
if (item != 0)
{
sum.setItem(i, j, item);
}
}
}
return true;
}
else
{
return false;
}
}

/* 稀疏矩阵的乘法 (a乘b) */
friend bool multiplyMatrix(TripleMatrix a, TripleMatrix b, TripleMatrix& result)
{
if (a.Columns == b.Rows)
{
// 初始化result的行列值
result.Rows = a.Rows;
result.Columns = b.Columns;

// 乘法计算
for (int i = 1; i <= result.Rows; i++)
{
for (int j = 1; j <= result.Columns; j++)
{
double sum = 0;
for (int k = 1; k <= a.Columns; k++)
{
sum += a.getItem(i, k) * b.getItem(k, j);
}
// 如果计算出来的结果不为0, 则插入到三元组中
if (sum != 0)
{
result.setItem(i, j, sum);
}
}
}
return true;
}
else
{
return false;
}
}
};

/* 稀疏矩阵的输入 */
void inputMatrix(int num, TripleMatrix& triple)
{
int i, j, item;
for (int index = 0; index < num; index++)
{
cout << "请依次输入行,列和非零元:";
cin >> i >> j >> item;
if (item != 0)
{
if (triple.setItem(i, j, item) == ERROR)
{
cout << "行号列号不正确,或者三元组数组满,不能正确存储!";
break;
}
}
}
}

int main()
{
int m, n, num;

cout << "请输入第一个矩阵的行数, 列数, 非零元素个数: ";
cin >> m >> n >> num;
cout << "第一个矩阵如下: " << endl;
TripleMatrix tripleA(m, n);
inputMatrix(num, tripleA);
tripleA.printMatrix();

cout << "\n请输入第二个矩阵的行数, 列数, 非零元素个数: ";
cin >> m >> n >> num;
cout << "第二个矩阵如下: " << endl;
TripleMatrix tripleB(m, n);
inputMatrix(num, tripleB);
tripleB.printMatrix();

TripleMatrix tripleResult; // 无参构造函数, 在函数中再初始化行数和列数
if (multiplyMatrix(tripleA, tripleB, tripleResult))
{
cout << "\n矩阵相乘后的结果如下: " << endl;
tripleResult.printMatrix();
}
else
{
cout << "\n这两个矩阵不能相乘!" << endl;
}

return 0;
}

/*乘法测试数据
3 3 2
1 1 5
2 3 1
3 2 2
1 1 2
3 1 4
*/

运行结果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: