首页 > 技术文章 > 稀疏矩阵的基本操作

xyqxyq 2018-12-25 10:28 原文

这是简版的,原版的一时半会找不到了。

中文的很容易乱码,我们直接用英文好了。

#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
#include <cmath>
#include <iomanip>
#define MAX 121
#define Elemtype int
using namespace std;

typedef struct {
    int i, j;
    Elemtype e;
}Triple;
//全局变量用于暂存矩阵相乘时的矩阵
Elemtype t1[MAX][MAX];
Elemtype t2[MAX][MAX];

typedef struct {
    Triple data[MAX + 1];
    int mu, nu, tu;
} TSMatrix;

int CreateSMatrix(TSMatrix &M)
{
    cout << "Please enter the number of the rows and columns." << endl;
    int col, row;
    cin >> row >> col;
    if (row==0) {
        cout << "The matrix is empty." << endl;
        return -1;
    }
    M.mu = row;
    M.nu = col;
    M.tu = row * col * 0.05; // % 5 Sparse Matrix 稀疏矩阵
    //随机数赋值,取余数
    srand(time(NULL));
    int num=sqrt(row*col);
    int tmp[M.tu];
    for (int i = 0; i < M.tu;i++) {
        //取不超过矩阵大小的随机行列
        int r = rand() % num;
        int c = rand() % num;
        int p = r * col + c;//合并
        tmp[i] = p;//值的大小取决于行列值
    }
    //存的是0行0列起始
    sort(tmp, tmp + M.tu);
    for (int i = 1; i <= M.tu;i++) {//拆分
        M.data[i].e = rand() % row * col;
        M.data[i].i = tmp[i - 1] / col;
        M.data[i].j = tmp[i - 1] % col;
    }
    cout << "Initialization succeeded." << endl;
    return 0;
}

int CreateMatrix(TSMatrix &M)
{
	cout << "Please enter the number of the rows and columns." << endl;
    int col, row;
    cin >> row >> col;
    if (row==0) {
        cout << "The matrix is empty." << endl;
        return -1;
    }
    M.mu = row;
    M.nu = col;
    M.tu = row * col;
    srand(time(NULL));
    //这实际上是一个满的“稀疏矩阵”
    for (int i=0;i<M.tu;i++) {
    	M.data[i].e=rand()%row;
    	M.data[i].i=i/col;
    	M.data[i].j=i%col;
	}
	cout << "Initialization succeeded." << endl;
	return 0;
}

int PrintSMatrix(TSMatrix M)
{
    if (M.tu==0) {
        cout << "Matrix is empty!" << endl;
        return -1;
    }
    //设置了一个指针,当指针所指的位置和稀疏矩阵的非零元位置相等时,进行输出和更新
    int p = M.data[1].i * M.nu + M.data[1].j;
    int k = 1;
    for (int i = 0; i < M.mu * M.nu;i++) {
        if (i%M.nu==0) {
            cout << endl;
        }
        if (p==i) {
            cout << setw(4) << M.data[k].e;
            if (k<=M.tu)
                k++;
            p = M.data[k].i * M.nu + M.data[k].j;
        }
        else {
            cout << setw(4) << "0";
        }
    }
    cout << endl;
    return 0;
}

int PrintMatrix(Elemtype t[MAX][MAX],int r,int c)
{
    for (int i = 0; i < r;i++) {
        for (int j = 0; j < c;j++) {
            cout <<setw(4)<< t[i][j];
        }
        cout << endl;
    }
    cout<<endl;
    return 0;
}

int Write(TSMatrix &M,Elemtype t[MAX][MAX])
{
    int k = 1;
    int p = M.data[1].i * M.nu + M.data[1].j;
    for (int i = 0; i < M.mu * M.nu;i++) {
        if (p==i) {
            t[M.data[k].i][M.data[k].j]=M.data[k].e;
            if (k<=M.tu)
                k++;
            p = M.data[k].i * M.nu + M.data[k].j;
        }
        else {
            int r = i / M.nu;
            int c = i % M.nu;
            t[r][c]=0;
        }
    }
    PrintMatrix(t, M.mu, M.nu);
    return 0;
}

int MultSMatrix(TSMatrix &M,TSMatrix &T)
{
    if (M.tu==0||T.tu==0) {
        cout << "Matrix is empty." << endl;
        return -1;
    }
    if (M.nu!=T.mu) {
        cout << "They can't multiply" << endl;
        return -1;
    }
    //稀疏矩阵转一般矩阵
    Write(M,t1);
    Write(T,t2);
    
    Elemtype sum;
    Elemtype t[MAX][MAX];
    for (int k = 0; k < T.nu;k++) {
        for (int i = 0; i < M.mu;i++) {
            sum = 0;
            for (int j = 0; j < M.nu;j++) {
                sum += t1[i][j] * t2[j][k];
            }
            t[i][k] = sum;
        }
    }
    PrintMatrix(t, M.mu, T.nu);
    return 0;
}

int TransposeSMatrix(TSMatrix &T,TSMatrix &M)
{
    if (M.tu==0) {
        cout << "Matrix is empty." << endl;
        return -1;
    }
    T.mu = M.mu;
    T.nu = M.nu;
    T.tu = M.tu;
    int num[M.nu + 1];
    for (int col = 1; col <= M.nu;col++) {
        num[col] = 0;
    }
    for (int t = 1; t <= M.tu;t++) {
        num[M.data[t].j]++;
    }
    int cpot[M.nu+1];
    cpot[1] = 1;
    for (int col = 2; col <= M.nu;col++) {
        cpot[col] = cpot[col - 1] + num[col - 1];
    }
    for (int p = 1; p <= M.tu;p++) {
        int col = M.data[p].j;
        int q = cpot[col];
        T.data[q].i = M.data[p].j;//重置过后的第二次转置出现了异常
        T.data[q].j = M.data[p].i;
        T.data[q].e = M.data[p].e;
        cpot[col]++;
        //这实际上默认了前一位的行号大于后一位的行号
        //因为行号转列号,所以前面先被处理的单元,它经过转换之后的列号
        //一定会小于后面被处理单元的列号,自然就可以让cpot[col]++,继续向后存储
    }
    cout << "Transpose successfully!" << endl;
    PrintSMatrix(T);
    return 0;
}

int main()
{
    int n,num;
    TSMatrix M,S,T,Q;
    cout << "Please enter the action you want to take.Enter 0 will exit." << endl
         << "1.Create sparse matrix M." << endl
         << "2.Create a generic matrix Q and compress the storage." << endl
         << "3.Print the sparse matrix." << endl
         << "4.Multiply the matrix M times the matrix T." << endl
         << "5.Transpose sparse matrix M." << endl;
    while (cin>>n&&n) {
        switch (n) {
            case 1:
                CreateSMatrix(M);
                break;
            case 2:
            	CreateMatrix(Q);
                PrintSMatrix(Q);
                break;
            case 3:
                PrintSMatrix(M);
                break;
            case 4:
                cout << "Please Create the matrix T(Sparse or Generic).1 represent the sparse,0 represent the generic." << endl;
                cin >> num;
                if (num)
                    CreateSMatrix(T);
                else
                    CreateMatrix(T);
                MultSMatrix(M, T);
                break;
            case 5:
                TransposeSMatrix(S,M);
                break;
        }
    }
    return 0;
}

 

推荐阅读