数据结构——稀疏矩阵之快速转置算法实现

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;
template<typename D>
class SMatrix
{
    public:
        struct DD//二维矩阵
        {
            int x,y;
            D **m;
            DD(int x,int y):x(x),y(y)
            {
                m = new D *[x];
                for (int i=0;i<y;i++) m[i] = new D[x];
            }
        };
        struct triplet//稀疏矩阵的三元组
        {
            int x,y;
            D data;
            triplet(int x,int y,D data):x(x),y(y),data(data){}
            bool operator < (const triplet & tmp)
            {
                return x == tmp.x ? y < tmp.y:x < tmp.x;
            }
        };
        vector<triplet> matrix;//存储稀疏矩阵
        int x;
        int y;
    public:
        SMatrix(){        //普通初始化
            this->x = 0;
            this->y = 0;
            this->matrix.clear();
        }
        SMatrix(vector<triplet> vt,int x,int y):matrix(vt),x(x),y(y){}//传入同类型的vector初始化
        SMatrix(DD &dd) // 传入规定的矩阵初始化
        {
            x = dd.x;
            y = dd.y;
            for (int i=0;i<dd.x;i++)
            {
                for (int j=0;j<dd.y;j++)
                {
                    if (dd.m[i][j])
                    {
                        matrix.push_back(triplet(i,j,dd.m[i][j]));
                    }
                }
            }
        }
        SMatrix<D> copy()
        {
            return SMatrix<D>(matrix);
        }
        void insert(int x,int y,D data)
        {
            matrix.push_back(triplet(x-1,y-1,data));
            this->x = max(x,this->x);
            this->y = max(y,this->y);
            sort(matrix.begin(),matrix.end());
        }
        static SMatrix Add(SMatrix &x,SMatrix &y)
        {

        }
        static SMatrix Sub(SMatrix &x,SMatrix &y)
        {

        }
        static SMatrix Mul(SMatrix &x,SMatrix &y)
        {

        }
        void fastTranspose()//稀疏矩阵快速转置算法实现
        {
            vector<triplet> tmp = matrix;
            int num[y]{0};
            //num存储每一列有多少非零元素
            for (int i=0;i<matrix.size();i++) num[matrix[i].y]++;
            int cpot[y]{0};
            //cpot记录每一列第一个元素在新的vector里的位置,因此每一列的所有元素所在的位置就可以通过cpot和num结合来定位了
            for (int i = 1;i<y;i++) cpot[i] = cpot[i-1] + num[i-1];
            for (int i=0;i<matrix.size();i++)
            {
            //这个for循环就是如上面所解释的,循环遍历所有的元素,然后找到应该每个元素应该在的位置,cpot[t.y]就是在定位
                triplet &t = matrix[i];triplet &k = tmp[cpot[t.y]];
                k.y = t.x;
                k.x = t.y;
                k.data = t.data;
                cpot[t.y]++;
            }
            swap(x,y);
            matrix = tmp;
        }
        void print()//矩阵输出,类python的形式,而且有点暴力
        {
            cout << "[";
            for (int i=0;i<x;i++)
            {
                for (int j=0;j<y;j++)
                {
                    bool exist = false;
                    for (int k = 0;k<matrix.size();k++)
                    {
                        if (i == matrix[k].x && j == matrix[k].y)
                        {
                            cout << matrix[k].data;
                            exist = true;
                        }
                        
                    }
                    if (!exist) cout << 0;
                    if (j != y-1)cout << ",";
                }
                if (i != x-1)cout << endl;
            }
            cout << "]" << endl;;
        }
};

void test1()//测试1
{
    SMatrix<int>::DD ddm(2,3);
    ddm.m[1][2] = 9;  
    for (int i=0;i<2;i++)
    {
        for (int j=0;j<3;j++)
        {
            cin >> ddm.m[i][j];
        }
    }
    SMatrix<int> m(ddm);
    m.fastTranspose();
    m.print();
}

void test2()//测试2
{
    SMatrix<int> sm;
    int n;cin >> n;
    int x,y,d;
    for (int i=0;i<n;i++)
    {
        cin >> x >> y >> d;
        sm.insert(x,y,d);
    }
    sm.print();
}

int main()
{
    test1();
    test2();
    return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值