C++面向对象实现稀疏矩阵的三元组表示

C++面向对象实现稀疏矩阵的三元组表示

项目结构

文件名字 用途
CmakeList.txt cmake文件
how.md 简述思路以及其他说明
main.cpp 主测试程序
SpMtx.cpp 核心实现文件
SpMtx.h 核心头文件

how.md

# 稀疏矩阵
- 是指在矩阵中,大部分元素都为零的情况,而只有少数非零元素。对于这种情况,为了节省存储空间,可以采用三元组表示法。

- 三元组表示法是指用三个数组来表示稀疏矩阵,分别存储非零元素的行、列坐标以及对应的值。

- 具体来说,假设一个 m × n 的稀疏矩阵中有 k 个非零元素,那么可以定义三个长度为 k 的数组:

row_idx:存储非零元素的行坐标;
col_idx:存储非零元素的列坐标;
value:存储非零元素的值


# 相关术语
#### 稀疏性(Sparsity):指矩阵中零元素的数量与元素总数的比值,用来衡量矩阵的稀疏程度。
#### 三元组压缩存储,如下理解

// 矩阵
0 0 0 0 0
0 0 2 0 0
0 1 0 0 0
0 0 0 3 0
0 0 0 0 0

// 表示
(2, 2, 2)
(3, 2, 1)
(4, 4, 3)

// 其中第一个三元组表示第二行第二列的元素为2,
// 第二个三元组表示第三行第二列的元素为1,
// 第三个三元组表示第四行第四列的元素为3。


#### 也可以这么表示 : 创建三个数组,分明别用来保存行、列、值

* 本文是基于三元组实现的方法

SpMtx.cpp

//
// Created by 20281 on 2023/5/5.
//

#include "SpMtx.h"

// vectors参数传入的是rows个数组,每个数组至少有cols个元素
SpMtx::SpMtx(int _rows, int _cols, Element** vectors) {
    rows = _rows;
    cols = _cols;
    length = 0;
    nodes = new Tuple [rows * cols];
    // length属性仅代表非0元素或者说nodes长度
    for (int r=0;r<rows;r++){
        for (int c=0;c<cols;c++){
            if (vectors[r][c] != .0){
                nodes[length] = Tuple {r, c, vectors[r][c]};
                ++length;
            }
        }
    }
}

SpMtx::~SpMtx() {
    delete[] nodes;
}

void SpMtx::printTuples() {
    cout << "\t===============当前稀疏组==============" <<endl;
    for (int i=0;i<length;i++){
        cout << "\t( " << nodes[i].row << ", " << nodes[i].col << ", " << nodes[i].value << " )";
        NEWLINE
    }
    cout << "\tOrigin-Shape is " << " ( " << rows << ", " << cols << " )" <<endl;
    cout << "\t=========================================" << endl;
}

void SpMtx::printMatrix() {
    cout << "\t===============当前稀疏矩阵==============" <<endl;
    int _count = 0;
    for (int r=0;r<rows;r++){
        cout << "\t[ ";
        for (int c=0;c<cols;c++){
            if (nodes[_count].col == c && nodes[_count].row == r){
                cout << nodes[_count].value << "  ";
                ++_count;
            }else{
                cout << 0 << "  ";
            }
        }
        cout << " ]\n";
    }
    cout << "\tOrigin-Shape is " << " ( " <<rows << ", " << cols << " )" <<endl;
    cout << "\t=========================================" << endl;
}

Element SpMtx::getSparsity() const{
    return (Element)length / (rows * cols);
}

SpMtx.h

//
// Created by 20281 on 2023/5/5.
//

#ifndef SPARSEMATRIX_SPMTX_H
#define SPARSEMATRIX_SPMTX_H

#include "iostream"
#include "iomanip"

using namespace std;

typedef double Element;

// 帮助我快速换行
#define NEWLINE cout << endl;

// 以下是稀疏矩阵两种不同的存储形式
// 使用三元组表示每个点
typedef struct _Tuple {
    int row;
    int col;
    Element value;
} Tuple;

class SpMtx {
private:
    Tuple * nodes;
    int rows;
    int cols;
public:
    int length;
    // methods
    explicit SpMtx(int _rows, int _cols, Element **vectors);
    ~SpMtx();
    // 以三元组呈现,另外打印形状
    void printTuples();
    // 以矩阵呈现,另外打印形状
    void printMatrix();
    // 输出稀疏度
    Element getSparsity() const;
};

#endif //SPARSEMATRIX_SPMTX_H

main.cpp

//
// Created by 20281 on 2023/5/5.
//

#include "SpMtx.h"

int main(){
    // 8个非0值
     Element base_datas[4][8] = {
            {0, 0, 0, 0, 0, 0, 2, 0},
            {.2, 0, 0, 3, 0, 5, .1, 0},
            {0, 0, 0, 0, 1, 1, 0, 0},
            {0, 0, 2, 0, 0, 0, 0, 0}
     };
     auto **data = new Element * [4];
     for (int i=0;i<4;i++) data[i] = new Element [8]    ;
     for (int i=0;i<4;i++){ for (int j=0;j<8;j++) { data[i][j] = base_datas[i][j]; } }
     auto matSparse = SpMtx(4, 8, data);
     cout << "非0值 : " << matSparse.length;NEWLINE
     matSparse.printTuples();
     matSparse.printMatrix();
     cout << fixed << setprecision(3) << "稀疏度 : " << matSparse.getSparsity();NEWLINE
     for (int i=0;i<4;i++) delete[] data[i];
     return 0;
}

终端运行结果

非0值 : 8                                       
        ===============当前稀疏组==============  
        ( 0, 6, 2 )                              
        ( 1, 0, 0.2 )                            
        ( 1, 3, 3 )                              
        ( 1, 5, 5 )                              
        ( 1, 6, 0.1 )                            
        ( 2, 4, 1 )                              
        ( 2, 5, 1 )                              
        ( 3, 2, 2 )                              
        Origin-Shape is  ( 4, 8 )                
        =========================================
        ===============当前稀疏矩阵==============
        [ 0  0  0  0  0  0  2  0   ]             
        [ 0.2  0  0  3  0  5  0.1  0   ]         
        [ 0  0  0  0  1  1  0  0   ]             
        [ 0  0  2  0  0  0  0  0   ]             
        Origin-Shape is  ( 4, 8 )                
        =========================================
稀疏度 : 0.250                                  


CmakeList.txt

cmake_minimum_required(VERSION 3.25)
project(SparseMatrix)

set(CMAKE_CXX_STANDARD 14)

include_directories(.)

add_executable(SparseMatrix
        main.cpp
        SpMtx.cpp
        SpMtx.h)

源代码下载 :SparseMartix · PythonnotJava/自己实现的数据结构与算法合集 - 码云 - 开源中国 (gitee.com)

你可能感兴趣的:(数据结构与算法,c++,矩阵,数据结构)