稀疏矩阵操作算法

测试: 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;
}
View Code

 

类头文件 : 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;
};
View Code

 

输入压缩矩阵: 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;
}
View Code

 

输入稀疏矩阵原形: 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;
}
View Code

 

输出压缩矩阵: 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;
        }
}
View Code

 

输出稀疏矩阵原形: 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;
}
View Code

 

转置算法: 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);
}
View Code

 

相加算法: 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);
    }
}
View Code

 

相乘算法: 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);
}
View Code


提供数据测试:

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
View Code

 

测试结果 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
-----------------结果
两个矩阵不符合相乘的条件, 无法进行乘法运算
请按任意键继续. . .
View Code

 

测试结果 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
请按任意键继续. . .
View Code

 

posted @ 2014-10-26 21:34  TabWeng  阅读(676)  评论(0编辑  收藏  举报