稀疏矩阵操作算法
测试: demo.cpp
#include "trituple.h" #include <iostream> using namespace std; int main(){ Trituple data1; Trituple data2; cout << "功能演示==========================================" << endl; cout << "功能1:输入已压缩的稀疏矩阵,转换成稀疏矩阵原形=====\n" << endl; TriSeqMatrix Ts = data1.input(); //输入已压缩 cout << "稀疏矩阵原形: " << endl; data1.output_p(Ts); //输出原形 cout << "\n==================================================" << endl; cout << "功能2:输入稀疏矩阵原形,转换成压缩稀疏矩阵=========\n" << endl; TriSeqMatrix Ts2 = data2.input_p(); data2.output(Ts2); cout << "\n==================================================" << endl; cout << "功能3:将稀疏矩阵转置==============================" << endl; cout << "转置功能1的稀疏矩阵===============================\n" << endl; data1.transposition(Ts); cout << "\n转置功能2的稀疏矩阵===============================\n" << endl; data2.transposition(Ts2); cout << "\n==================================================" << endl; cout << "功能4:将稀疏矩阵1 和 2相加========================\n" << endl; data1.add(Ts, Ts2); cout << "\n==================================================" << endl; cout << "功能5:将稀疏矩阵1 和 2相乘========================\n" << endl; data1.multiply(Ts, Ts2); return 0; }
类头文件 : trituple.h
#define MAXSIZE 200 typedef int DataType; typedef struct{ int i,j; DataType e; }Trituple_s; typedef struct{ Trituple_s data[MAXSIZE]; int m, n, len; //行数, 列数, 长度 }TriSeqMatrix; class Trituple{ public: void transposition(TriSeqMatrix Ts); //转置 void add(TriSeqMatrix Ts, TriSeqMatrix Ts2); //相加 void multiply(TriSeqMatrix Ts, TriSeqMatrix Ts2); //相乘 TriSeqMatrix input(); //输入 TriSeqMatrix input_p(); //输入原始 void output_p(TriSeqMatrix Ts); //输出原形 void output(TriSeqMatrix Ts); //输出压缩 private: Trituple_s Tt; TriSeqMatrix Ts; };
输入压缩矩阵: input.cpp
#include <iostream> #include "trituple.h" using namespace std; TriSeqMatrix Trituple::input(){ cout << "请输入稀疏矩阵的行数, 列数, 非零元素个数: "; cin >> Ts.m >> Ts.n >> Ts.len; int i = 0; int k = 0; //记录元素 while (i < Ts.len){ cout << "请输入稀疏矩阵的非零元素,分别输入行,列, 和值: "; cin >> Tt.i >> Tt.j >> Tt.e; if (Tt.i >= Ts.m || Tt.j >= Ts.n){ cout << "输入的值超出了范围!请重新输入!" << endl; continue; } else{ Ts.data[k].i = Tt.i; Ts.data[k].j = Tt.j; Ts.data[k].e = Tt.e; k++; } i++; } return Ts; }
输入稀疏矩阵原形: input_p.cpp
#include <iostream> using namespace std; #include "trituple.h" TriSeqMatrix Trituple::input_p(){ cout << "请输入稀疏矩阵的行数, 列数, 非零元素个数: "; cin >> Ts.m >> Ts.n >> Ts.len; cout << "请规范输入稀疏矩阵: " << endl; int k_temp = 0; DataType indata; //用来接受输入 for (int i = 0; i < Ts.m; i++){ for (int j = 0; j < Ts.n; j++){ cin >> indata; if (indata != 0){ Ts.data[k_temp].i = i; Ts.data[k_temp].j = j; Ts.data[k_temp].e = indata; k_temp++; } } } return Ts; }
输出压缩矩阵: output.cpp
#include <iostream> using namespace std; #include "trituple.h" void Trituple::output(TriSeqMatrix Ts){ cout << "稀疏矩阵原形压缩后为(行,列,值): "<< endl; for (int i = 0; i < Ts.len; i++){ cout << Ts.data[i].i << " " << Ts.data[i].j << " " << Ts.data[i].e << endl; } }
输出稀疏矩阵原形: output_p.cpp
#include <iostream> using namespace std; #include "trituple.h" void Trituple::output_p(TriSeqMatrix Ts){ int k_temp = 0; //用来遍历K的值 int j = 0; for (int i = 0;i < Ts.m; i++){ //扫描行 for (j = 0; j < Ts.n; j++){ //扫描子列 if (Ts.data[k_temp].i == i && Ts.data[k_temp].j == j){ cout << Ts.data[k_temp].e << " "; if (j == Ts.n - 1 ){ cout << endl; } k_temp++; } else{ cout << "0 "; if (j == Ts.n - 1 ){ cout << endl; } } } } return; }
转置算法: transposition.cpp
#include <iostream> using namespace std; #include "trituple.h" void Trituple::transposition(TriSeqMatrix Ts){ output_p(Ts); cout << "转置 ======>>>" << endl; int temp = 0; TriSeqMatrix temp_ts; temp = Ts.m; Ts.m = Ts.n; Ts.n = temp; int i = 0; for (i = 0; i < Ts.len; i++){ temp = Ts.data[i].i; Ts.data[i].i = Ts.data[i].j; Ts.data[i].j = temp; } int j = 0; for (i = 0; i < Ts.len; i++){ for (j = i + 1; j < Ts.len; j++){ if (Ts.data[i].i > Ts.data[j].i){ temp_ts.data[1] = Ts.data[i]; Ts.data[i] = Ts.data[j]; Ts.data[j] = temp_ts.data[1]; } else{ if (Ts.data[i].i == Ts.data[j].i){ if (Ts.data[i].j > Ts.data[j].j){ temp_ts.data[1] = Ts.data[i]; Ts.data[i] = Ts.data[j]; Ts.data[j] = temp_ts.data[1]; } } } } } output_p(Ts); }
相加算法: add.cpp
#include <iostream> using namespace std; #include "trituple.h" void Trituple::add(TriSeqMatrix Ts, TriSeqMatrix Ts2){ TriSeqMatrix addTs; if (Ts.m != Ts2.m || Ts.n != Ts.n){ cout << "两个稀疏矩阵大小不相等, 无法进行相加\n" << endl; } else{ addTs.n = Ts.n; //给出列 addTs.m = Ts.m; //给出行 int small = 0; //小的在前面 int big = 0; if (Ts.len < Ts2.len){ small = Ts.len; big = Ts2.len; } else{ small = Ts2.len; big = Ts.len; } int temp = 0; int j = 0; for (int i = 0; i < big; i++){ for (; j < small; ){ if (Ts.data[i].i < Ts2.data[j].i){ addTs.data[temp] = Ts.data[i]; temp++; break; } else{ if (Ts.data[i].i > Ts2.data[j].i){ addTs.data[temp] = Ts2.data[j]; temp++; j++; break; } else{ if (Ts.data[i].j > Ts2.data[j].j){ addTs.data[temp] = Ts2.data[j]; temp++; j++; break; } else{ if (Ts.data[i].j < Ts2.data[j].j){ addTs.data[temp] = Ts.data[i]; temp++; break; } else{ addTs.data[temp].i = Ts.data[i].i; addTs.data[temp].j = Ts.data[i].j; addTs.data[temp].e = Ts.data[i].e + Ts2.data[j].e; temp++; j++; break; } } } } } if (j == small){ addTs.data[temp] = Ts.data[i]; temp++; } } addTs.len = temp - 1; //显示 output_p(Ts); cout << "\t\t相加 + " << endl; output_p(Ts2); cout << "-----------------结果" << endl; output_p(addTs); } }
相乘算法: multiply.cpp
#include <iostream> using namespace std; #include "trituple.h" void Trituple::multiply(TriSeqMatrix Ts, TriSeqMatrix Ts2){ output_p(Ts); cout << "\t\t相乘 + " << endl; output_p(Ts2); cout << "-----------------结果" << endl; TriSeqMatrix Mu; Mu.m = Ts.m; Mu.n = Ts2.n; if (Ts.n != Ts2.m){ cout << "两个矩阵不符合相乘的条件, 无法进行乘法运算" << endl; return; } //预处理Ts2,得出列的种类 //int temp = Ts2.data[0].j; //第一个值得列 int *Ts2Hang = new int(Ts2.n); //动态内存分配,志华提供 //int Ts2Hang[Ts2.len]; int k = 0; for (k = 0; k < Ts2.n; k++){ int t = 0; for (t = 0; t < Ts2.len; t++){ if (Ts2.data[t].j == k){ Ts2Hang[k] = Ts2.data[t].j; break; } } } k = 0; int sum = 0; int temp = 0; int power2 = 0; //尾 int power = 0; //头 for (int i = 0; i < Ts.len; i++){ for (int j = 0; j < Ts2.len; j++){ if (Ts2.data[j].j == Ts2Hang[k]){ if (Ts2.data[j].i == Ts.data[i].j){ sum += Ts.data[i].e * Ts2.data[j].e; break; } } } if (Ts.data[i].i != Ts.data[i+1].i){ Mu.data[temp].i = Ts.data[i].i; Mu.data[temp].j = Ts2Hang[k]; Mu.data[temp].e = sum; temp++; sum = 0; power = power2; power2 = i; if (k == Ts2.n - 1){ i = power2; k = 0; } else{ k++; i = power; } } } output_p(Mu); }
提供数据测试:
6 7 9 0 3 9 1 1 3 2 2 7 2 3 2 3 0 7 3 4 -2 4 2 4 4 3 7 5 4 5 6 7 9 0 0 0 9 0 0 0 0 3 0 0 0 0 0 0 0 7 2 0 0 0 7 0 0 0 -2 0 0 0 0 4 7 0 0 0 0 0 0 0 5 0 0 7 6 9 0 3 7 1 1 3 2 2 7 2 4 4 3 0 9 3 2 2 3 4 7 4 3 -2 4 5 5 7 6 9 0 0 0 7 0 0 0 3 0 0 0 0 0 0 7 0 4 0 9 0 2 0 7 0 0 0 0 -2 0 5 0 0 0 0 0 0 0 0 0 0 0 0 7 6 9 3 0 9 1 1 3 2 2 7 3 2 2 0 3 7 4 3 -2 2 4 4 3 4 7 4 5 5 7 6 6 0 3 1 0 5 2 2 0 4 3 4 7 6 2 8 6 5 9 6 2 5 0 3 0 0 0 0 5 0 1 2 0 4 3 4 4 0 0 2 0 3 9 1 1 -1 2 3 5 4 2 3 2 0 0 -1 3 0 0 0 5 4 8 0 1 1 0 3 1 1 0 1 2 0 2 2 3 1 3 0 3 3 1 1 4 3 1 4 3 12 2 3 1 3 4 1 4 1 1 1 1 1 2 4 6 0 0 1 0 2 3 0 3 -1 1 0 2 1 1 1 1 3 2 4 3 10 4 1 0 -1 1 3 2 0 1 1 3 4
测试结果 1:
功能演示========================================== 功能1:输入已压缩的稀疏矩阵,转换成稀疏矩阵原形===== 请输入稀疏矩阵的行数, 列数, 非零元素个数: 6 7 9 请输入稀疏矩阵的非零元素,分别输入行,列, 和值: 0 3 9 请输入稀疏矩阵的非零元素,分别输入行,列, 和值: 1 1 3 请输入稀疏矩阵的非零元素,分别输入行,列, 和值: 2 2 7 请输入稀疏矩阵的非零元素,分别输入行,列, 和值: 2 3 2 请输入稀疏矩阵的非零元素,分别输入行,列, 和值: 3 0 7 请输入稀疏矩阵的非零元素,分别输入行,列, 和值: 3 4 -2 请输入稀疏矩阵的非零元素,分别输入行,列, 和值: 4 2 4 请输入稀疏矩阵的非零元素,分别输入行,列, 和值: 4 3 7 请输入稀疏矩阵的非零元素,分别输入行,列, 和值: 5 4 5 稀疏矩阵原形: 0 0 0 9 0 0 0 0 3 0 0 0 0 0 0 0 7 2 0 0 0 7 0 0 0 -2 0 0 0 0 4 7 0 0 0 0 0 0 0 5 0 0 ================================================== 功能2:输入稀疏矩阵原形,转换成压缩稀疏矩阵========= 请输入稀疏矩阵的行数, 列数, 非零元素个数: 6 7 9 请规范输入稀疏矩阵: 0 0 0 9 0 0 0 0 3 0 0 0 0 0 0 0 7 2 0 0 0 7 0 0 0 -2 0 0 0 0 4 7 0 0 0 0 0 0 0 5 0 0 稀疏矩阵原形压缩后为(行,列,值): 0 3 9 1 1 3 2 2 7 2 3 2 3 0 7 3 4 -2 4 2 4 4 3 7 5 4 5 ================================================== 功能3:将稀疏矩阵转置============================== 转置功能1的稀疏矩阵=============================== 0 0 0 9 0 0 0 0 3 0 0 0 0 0 0 0 7 2 0 0 0 7 0 0 0 -2 0 0 0 0 4 7 0 0 0 0 0 0 0 5 0 0 转置 ======>>> 0 0 0 7 0 0 0 3 0 0 0 0 0 0 7 0 4 0 9 0 2 0 7 0 0 0 0 -2 0 5 0 0 0 0 0 0 0 0 0 0 0 0 转置功能2的稀疏矩阵=============================== 0 0 0 9 0 0 0 0 3 0 0 0 0 0 0 0 7 2 0 0 0 7 0 0 0 -2 0 0 0 0 4 7 0 0 0 0 0 0 0 5 0 0 转置 ======>>> 0 0 0 7 0 0 0 3 0 0 0 0 0 0 7 0 4 0 9 0 2 0 7 0 0 0 0 -2 0 5 0 0 0 0 0 0 0 0 0 0 0 0 ================================================== 功能4:将稀疏矩阵1 和 2相加======================== 0 0 0 9 0 0 0 0 3 0 0 0 0 0 0 0 7 2 0 0 0 7 0 0 0 -2 0 0 0 0 4 7 0 0 0 0 0 0 0 5 0 0 相加 + 0 0 0 9 0 0 0 0 3 0 0 0 0 0 0 0 7 2 0 0 0 7 0 0 0 -2 0 0 0 0 4 7 0 0 0 0 0 0 0 5 0 0 -----------------结果 0 0 0 18 0 0 0 0 6 0 0 0 0 0 0 0 14 4 0 0 0 14 0 0 0 -4 0 0 0 0 8 14 0 0 0 0 0 0 0 10 0 0 ================================================== 功能5:将稀疏矩阵1 和 2相乘======================== 0 0 0 9 0 0 0 0 3 0 0 0 0 0 0 0 7 2 0 0 0 7 0 0 0 -2 0 0 0 0 4 7 0 0 0 0 0 0 0 5 0 0 相乘 + 0 0 0 9 0 0 0 0 3 0 0 0 0 0 0 0 7 2 0 0 0 7 0 0 0 -2 0 0 0 0 4 7 0 0 0 0 0 0 0 5 0 0 -----------------结果 两个矩阵不符合相乘的条件, 无法进行乘法运算 请按任意键继续. . .
测试结果 2:
功能演示========================================== 功能1:输入已压缩的稀疏矩阵,转换成稀疏矩阵原形===== 请输入稀疏矩阵的行数, 列数, 非零元素个数: 2 4 6 请输入稀疏矩阵的非零元素,分别输入行,列, 和值: 0 0 1 请输入稀疏矩阵的非零元素,分别输入行,列, 和值: 0 2 3 请输入稀疏矩阵的非零元素,分别输入行,列, 和值: 0 3 -1 请输入稀疏矩阵的非零元素,分别输入行,列, 和值: 1 0 2 请输入稀疏矩阵的非零元素,分别输入行,列, 和值: 1 1 1 请输入稀疏矩阵的非零元素,分别输入行,列, 和值: 1 3 2 稀疏矩阵原形: 1 0 3 -1 2 1 0 2 ================================================== 功能2:输入稀疏矩阵原形,转换成压缩稀疏矩阵========= 请输入稀疏矩阵的行数, 列数, 非零元素个数: 4 3 10 请规范输入稀疏矩阵: 4 1 0 -1 1 3 2 0 1 1 3 4 稀疏矩阵原形压缩后为(行,列,值): 0 0 4 0 1 1 1 0 -1 1 1 1 1 2 3 2 0 2 2 2 1 3 0 1 3 1 3 3 2 4 ================================================== 功能3:将稀疏矩阵转置============================== 转置功能1的稀疏矩阵=============================== 1 0 3 -1 2 1 0 2 转置 ======>>> 1 2 0 1 3 0 -1 2 转置功能2的稀疏矩阵=============================== 4 1 0 -1 1 3 2 0 1 1 3 4 转置 ======>>> 4 -1 2 1 1 1 0 3 0 3 1 4 ================================================== 功能4:将稀疏矩阵1 和 2相加======================== 两个稀疏矩阵大小不相等, 无法进行相加 ================================================== 功能5:将稀疏矩阵1 和 2相乘======================== 1 0 3 -1 2 1 0 2 相乘 + 4 1 0 -1 1 3 2 0 1 1 3 4 -----------------结果 9 -3 0 0 0 11 请按任意键继续. . .
作者:Tab Weng
Email:hlwyfeng(Geek)gmail.com 请将(Geek)换成@
出处:博客园 Tab Weng的博客:http://www.cnblogs.com/hlwyfeng
声明:本文采用知识共享署名-非商业性使用-禁止演绎 3.0 未本地化版本许可协议,允许重新传播和转载分享,但必须在正文显著位置注明署名及原文来源。
Email:hlwyfeng(Geek)gmail.com 请将(Geek)换成@
出处:博客园 Tab Weng的博客:http://www.cnblogs.com/hlwyfeng
声明:本文采用知识共享署名-非商业性使用-禁止演绎 3.0 未本地化版本许可协议,允许重新传播和转载分享,但必须在正文显著位置注明署名及原文来源。