zoukankan      html  css  js  c++  java
  • C++实现矩阵压缩

    C++实现矩阵压缩

    转置运算时一种最简单的矩阵运算。对于一个m*n的矩阵M,他的转置矩阵T是一个n*m的矩阵,且T(i,j) = M(j,i).

    一个稀疏矩阵的转置矩阵仍然是稀疏矩阵。

    矩阵转置

    方案一:

    1将矩阵的行列值相互交换

    2将每个原则中的i j 相互交换

    3重新排列三元组之间的次序

    这种方法实现比较简单,一次迭代交换i j 值。

    然后就是两层循环进行排序操作了。

    方案二

    具体实心步骤:

    1 迭代遍历,统计列中元素个数

    2 由1的结果迭代计算每一列中元素起始位置

    3 依据2中得到数据进行转置操作

    代码实现如下

    //稀疏矩阵
    #pragma once
    #include <vector>
    template<class T>
    class Trituple
    {
    public:
        Trituple(int row, int col, T& n)
            :_row(row)
            , _col(col)
            , _value(n)
        {}
        int _row;
        int _col;
        T _value;
    };
    
    template<class T>
    class SparseMatrix//稀疏矩阵
    {
    public:
        SparseMatrix(T*a, const int m, const int n, T& invalid)///行序排列
            :_rowSize(m)
            , _colSize(n)
            , _invalid(invalid)
        {
            size_t index = 0;
            for (int i = 0; i < _rowSize; ++i)
            {
                for (int j = 0; j < _colSize; ++j)
                {
                    if (a[i*n + j] != _invalid)
                    {
                        _array.push_back(*(new Trituple<T>(i, j, a[i*n + j])));
                        //_array[index++] = (new Trituple<T>(i,j,a[i*n+j]));
                    }
                }
            }
        }
    
        void Print()
        {
            size_t index = 0;
            for (int i = 0; i < _rowSize; ++i)
            {
                for (int j = 0; j < _colSize; ++j)
                {
                    //if (_array[i*_colSize + j]._value != _invalid)
                    if ((_array[index]._row == i)&&(_array[index]._col == j))
                    {
                        cout << _array[index++]._value << "->";
                    }
                    else
                    {
                        cout << _invalid<<" ->";
                    }
                }
                cout << endl;
            }
            cout << endl;
        }
    
        //转置方案:交换行列大小 值,交换元祖内部行列值. 重新排序vector;
        SparseMatrix<T> Transpose()
        {
            SparseMatrix<T> x(*this);
            ::swap(x._rowSize, x._colSize);
            x._array.clear();
            int i = 0;
            for (int j = 0; j < _colSize; ++j)
            {
                i = 0;
                while (i < _array.size())
                {
                    if (j == _array[i]._col)
                    {
                        //////////////////////////////////////////////////////////////////
                        //Trituple<T> t(_array[i]._row, _array[i]._col, _array[i]._value);
                        Trituple<T> t(_array[i]._col, _array[i]._row, _array[i]._value);
                        x._array.push_back(t);
                    }
                    ++i;
                }
            }
            return x;
        }
        SparseMatrix<T> FastTranspose()
        {
            //①:计算并保存每一列中非0元的个数;
            //②:求col列中第一个非0元在矩阵中的行位置。
            //③:依据以上,进行插入操作,并且更新cpot中的值
            SparseMatrix<T> x(*this);
            x._colSize = _rowSize;
            x._rowSize = _colSize;
            x._invalid = _invalid;
            if (_array.size())
            {
                int* RowCount = new int[_colSize];    //列中元素数
                int* RowStart = new int[_colSize];    //列中元素起始位置
                memset(RowCount, 0, sizeof(int)*_colSize);
                memset(RowStart, 0, sizeof(int)*_colSize);
                int index = 0;
                while (index < _array.size())  //一次迭代O(n)
                {
                    ++RowCount[_array[index++]._col];
                }
                index = 1;
                while (index < _colSize)      //O(n)
                {
                    RowStart[index] = RowStart[index - 1] + RowCount[index - 1];
                    ++index;
                }
                //执行快速转置
                int i = 0;
                while (i < _array.size())  //两次迭代 O(n)
                {
                    int col = _array[i]._col;
                    int start = RowStart[col];
                    x._array[start]._row = _array[i]._col;
                    x._array[start]._col = _array[i]._row;
                    x._array[start]._value = _array[i]._value;
                    ++RowStart[col];
                    i++;
                }
                delete[]RowCount;
                delete[]RowStart;
            }//if
            return x;
        }
        ~SparseMatrix()
        {
        }
    private:
        vector<Trituple<T> >  _array;
        size_t _rowSize;
        size_t _colSize;
        T _invalid;
    };
  • 相关阅读:
    微信小程序知识点梳理
    Vue基础知识梳理
    JQuery总结
    JS实现简单斗地主效果
    JS应用猜数游戏
    JS创建一个数组1.求和 2.求平均值 3.最大值 4.最小值 5.数组逆序 6.数组去重 0.退出
    JS数组的基本操作方法
    JS,ATM代码
    简单理解Vue中的nextTick
    Vue keep-alive实践总结
  • 原文地址:https://www.cnblogs.com/lang5230/p/5271602.html
Copyright © 2011-2022 走看看