数据结构之 矩阵 模板类

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

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

#include<iostream>
#ifndef _H_MYMATRIX_H
#define _H_MYMATRIX_H

template<class T>
class myMatrix;

template<class T>
std::ostream& operator<<(std::ostream& out, const myMatrix<T>& 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<T>& otherMatrix);
    ~myMatrix();

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

     myMatrix<T>& operator=(const myMatrix<T>& otherMatrix);
     myMatrix<T> operator+(const myMatrix<T>& otherMatrix);
     myMatrix<T> operator+(const T val);
     myMatrix<T> operator-(const myMatrix<T>& otherMatrix);
     myMatrix<T> operator-(T val);
     myMatrix<T> operator*(const myMatrix<T>& otherMatrix);
     myMatrix<T> 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<T>::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<T>::myMatrix(const myMatrix<T>& 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<T>::~myMatrix()
{
    delete[] (this->m_ptr);
}

template<class T>
myMatrix<T>& myMatrix<T>::operator=(const myMatrix<T>& 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<T> myMatrix<T>::operator+(const myMatrix<T>& otherMatrix)
{
    if (m_col != otherMatrix.cols() || m_row != otherMatrix.rows())
    {
        throw("DimensionNotMatched");
    }
    myMatrix<T> 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<T> myMatrix<T>::operator+(const T val)
{
    myMatrix<T> 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<T> myMatrix<T>::operator-(const myMatrix<T>& otherMatrix)
{
    if (m_col != otherMatrix.cols() || m_row != otherMatrix.rows())
    {
        return;
    }
    myMatrix<T> 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<T> myMatrix<T>::operator-(T val)
{
    myMatrix<T> 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<T> myMatrix<T>::operator*(const myMatrix<T>& otherMatrix)
{
    if(this->m_col == otherMatrix.rows())
    {
        myMatrix<T> 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<T> myMatrix<T>::operator*(T val)
{
    myMatrix<T> 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<T>::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<T>::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<T>::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<T>& otherMatrix)
{
    otherMatrix.output(out);
    return out;
}

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

#include <iostream>
#include "myMatrix.cpp"

void main(void)
{
    int row = 3;
    int col = 4;
    myMatrix<int> 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<<mat<<std::endl;  
    myMatrix<int> mat1 = mat;

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

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

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

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

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

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

    std::system("pause");
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值