数据结构之 矩阵 模板类

28日更新:我按照之前的约定,写完啦!

先预约一片在这里,最近两天把他写完(其实已经写完了,只是还没有誊写到个人笔记本上)

#include
#ifndef _H_MYMATRIX_H
#define _H_MYMATRIX_H

template<class T>
class myMatrix;

template<class T>
std::ostream& operator<<(std::ostream& out, const myMatrix& otherMatrix);

template<class T>
void swap(T& val1, T& val2);

template<class T>
class myMatrix
{
public:
    myMatrix(const int row = 1, const int col = 1);
    myMatrix(const myMatrix& otherMatrix);
    ~myMatrix();

    int rows(void) const {return m_row;}
    int cols(void) const {return m_col;}

     myMatrix& operator=(const myMatrix& otherMatrix);
     myMatrix operator+(const myMatrix& otherMatrix);
     myMatrix operator+(const T val);
     myMatrix operator-(const myMatrix& otherMatrix);
     myMatrix operator-(T val);
     myMatrix operator*(const myMatrix& otherMatrix);
     myMatrix operator*(T val);
     T& operator()(const int row, const int col);

     void transpose(void);

    void output(std::ostream& out);
private:
    int m_col;
    int m_row;
    T* m_ptr;
};

#endif

template<class T>
myMatrix::myMatrix(const int row = 1, const int col = 1)
{
    if(col <= 0 || row <= 0)
    {
        return;
    }
    m_row = row;
    m_col = col;
    m_ptr = new T[row * col];
    memset(this->m_ptr, 0, row * col * sizeof(T));///2017 11 02晚上增加*sizeof(T),这很重要
}

template<class T>
myMatrix::myMatrix(const myMatrix& otherMatrix)
{
    m_row = otherMatrix.rows();
    m_col = otherMatrix.cols();
    m_ptr = new T[m_col * m_row];
    memcpy(m_ptr, otherMatrix.m_ptr, m_col * m_row * sizeof(T));
}

template<class T>
myMatrix::~myMatrix()
{
    delete[] (this->m_ptr);
}

template<class T>
myMatrix& myMatrix::operator=(const myMatrix& otherMatrix)
{
    if(&otherMatrix != this)
    {
        delete[] (this->m_ptr);
        m_row = otherMatrix.rows();
        m_col = otherMatrix.cols();
        m_ptr = new T[m_col * m_row];
        memcpy(m_ptr, otherMatrix.m_ptr, m_col * m_row * sizeof(T));
    }
    return (*this);
}

template<class T>
myMatrix myMatrix::operator+(const myMatrix& otherMatrix)
{
    if (m_col != otherMatrix.cols() || m_row != otherMatrix.rows())
    {
        throw("DimensionNotMatched");
    }
    myMatrix mat(m_row, m_col);
    for(int ii = 0; ii < m_col * m_row; ii++)
    {
        mat.m_ptr[ii] = this->m_ptr[ii] + otherMatrix.m_ptr[ii];
    }
    return mat;
}

template<class T>
myMatrix myMatrix::operator+(const T val)
{
    myMatrix mat(m_row, m_col);
    for(int ii = 0; ii < m_col * m_row; ii++)
    {
        mat.m_ptr[ii] = this->m_ptr[ii] + val;
    }
    return mat;
}

template<class T>
myMatrix myMatrix::operator-(const myMatrix& otherMatrix)
{
    if (m_col != otherMatrix.cols() || m_row != otherMatrix.rows())
    {
        return;
    }
    myMatrix mat(m_row, m_col);
    for(int ii = 0; ii < m_col * m_row; ii++)
    {
        mat.m_ptr[ii] = this->m_ptr[ii] - otherMatrix.m_ptr[ii];
    }
    return mat;
}

template<class T>
myMatrix myMatrix::operator-(T val)
{
    myMatrix mat(m_row, m_col);
    for(int ii = 0; ii < m_col * m_row; ii++)
    {
        mat.m_ptr[ii] = this->m_ptr[ii] - val;
    }
    return mat;
}

template<class T>
myMatrix myMatrix::operator*(const myMatrix& otherMatrix)
{
    if(this->m_col == otherMatrix.rows())
    {
        myMatrix mat(this->m_row, otherMatrix.cols());
        for(int ii = 0; ii < this->m_row; ii++)
        {
            for(int jj = 0; jj < otherMatrix.cols(); jj++)
            {
                mat.m_ptr[ii * otherMatrix.cols() + jj] = 0;
                for(int kk = 0; kk < this->m_col; kk++)
                {
                    mat.m_ptr[ii * otherMatrix.cols() + jj] = mat.m_ptr[ii * otherMatrix.cols() + jj] + 
                        this->m_ptr[ii * this->m_col + kk] * otherMatrix.m_ptr[kk * otherMatrix.cols() + jj];
                }
            }
        }
        return mat;
    }
    else
    {
        throw("DimensionNotMatched");
    }
}

template<class T>
myMatrix myMatrix::operator*(T val)
{
    myMatrix mat(m_row, m_col);
    if(0 == val)
    {
        memset(mat.m_ptr, 0, m_col * m_row);
    }
    else
    {
        for(int ii = 0; ii < m_col * m_row; ii++)
        {
            mat.m_ptr[ii] = this->m_ptr[ii] * val;
        }
    }
    return mat;
}

template<class T>
T& myMatrix::operator()(const int row, const int col)
{
    if(row > 0 && row <= m_row && col <= m_col && col > 0 )
    {
        return (this->m_ptr[(row - 1) * m_col + col - 1]);
    }///2017 11 02增加下面else部分
    else
    {
        throw("WrongIndex");
    }
}

template<class T>
void myMatrix::transpose(void)
{
    思路:通过重新申请一块内存来,将原来的元素按照转置之后的顺序排列
    T* ptr = new T[this->m_col * this->m_row];
    for(int ii = 0;ii < this->m_row; ii++)
    {
        for(int jj = 0; jj < this->m_col; jj++)
        {
            ptr[jj * this->m_row + ii] = this->m_ptr[ii * this->m_col +jj];
        }
    }
    swap(this->m_col, this->m_row);
    delete[] (this->m_ptr);
    this->m_ptr = ptr;
}

template<class T>
void myMatrix::output(std::ostream& out)
{
    out<<"地址为:"<<this<<std::endl;
    for(int ii = 0; ii < m_row; ii++)
    {
        for(int jj = 0; jj < m_col; jj++)
        {
             out<<"\t"<<(this->m_ptr[ii * m_col + jj]);
        }
        out<<std::endl;
    }
}

template<class T>
void swap(T& val1, T& val2)
{
    val1 = val1 + val2;
    val2 = val1 - val2;
    val1 = val1 - val2;
}

template<class T>
std::ostream& operator<<(std::ostream& out, myMatrix& otherMatrix)
{
    otherMatrix.output(out);
    return out;
}

还有很多的问题,还需要测试(28日测试完毕,好像没有什么问题了,请大家也帮忙测试一下)

#include 
#include "myMatrix.cpp"

void main(void)
{
    int row = 3;
    int col = 4;
    myMatrix mat(row, col);

    for(int ii = 0; ii < row; ii++)
    {
        for(int jj = 0; jj < col; jj++)
        {
            mat(ii+1, jj+1) = ii + jj * jj;
        }
    }
    std::cout<::endl;  
    myMatrix mat1 = mat;

    mat.transpose();
    std::cout<::endl;

    try
    {
        myMatrix mat2 = mat * mat1;
        std::cout<::endl;
    }
    catch(char* ex)
    {
        std::cout<::endl;
    }

    myMatrix mat3;
    mat3 = mat + 6;
    std::cout<::endl; 

    mat3 = mat + mat;
    std::cout<::endl; 

    mat3 = mat * 6;
    std::cout<::endl; 

    myMatrix mat4(mat3);
    std::cout<::endl; 

    std::system("pause");
}

/ 发现一个问题,模板类不太能够容忍return;的写法,如果函数的定义是要求返回值的,使用了这个不会编译通过,所以建议改成不符合的就throw异常

你可能感兴趣的:(工作上的学习)