Puzzle

我的Matrix

    B.第二版

    这个小程序是增强版本。

    1。 程序基本说明：在前一个版本基础上进一步实现矩阵与数的乘法，矩阵的乘法，加法（减法忘了实现了，不过可以用*-1再加来做，所

    	以。。。），矩阵的复制(操作符=），矩阵的旋转（transposition即绕主轴翻转180度)。

    2。 程序思路：在矩阵的操作符重载后我返回矩阵的引用以便进行操作符的cascade,如M*2*4。

    3。 主要函数介绍：

         A. void mul(int source, int dest, double scalor);

    	void mul(int dest, double scalor);

    	内部方法第一个是把source行乘以scalor对应相加到dest行的对应项。第二个把dest行的每个元素乘以scalor.

         B. Matrix& operator *(Matrix otherMatrix);  矩阵的乘法，我为了省事，就在局部声明了一个临时矩阵以便记载结果，然后

    	再用复制的方法返回矩阵。

    4。 不足之处：

    	A. 时间比较少，方法写的比较粗糙。

    #include <iostream>
    #include <cmath>
    #include <fstream>

    using namespace std;

    const int MaxRow = 10;
    const int MaxCol = 10;
    const double LIMIT = 0.01;

    class Matrix
    {
    private:
    	int rowNum;
    	int colNum;
    	double lst[MaxRow][MaxCol];
    	void mul(int source, int dest, double scalor);
    	void mul(int dest, double scalor);

    public:
    	Matrix();
    	int row() const {return rowNum;}
    	int col() const {return colNum;}
    	void setRow(const int newRow) { rowNum = newRow;}
    	void setCol(const int newCol) { colNum = newCol;}
    	void display();
    	double& items(int r, int c);
    	void initialize();
    	void readFromFile(const char* fileName);
    	void echelon(int r, bool reduced=true);
    	Matrix& operator*(double i);
    	Matrix& operator *(Matrix otherMatrix);
    	Matrix& operator = (Matrix other);
    	Matrix& operator+(Matrix other);
    	Matrix& transposition();

    };

    int main()
    {
    	Matrix M, N;
    	M.readFromFile("c:\\nick.txt");
    	N = M;
    	cout<<"\nthis is M\n";
    	M.display();
    	M*2;
    //	M.echelon(0, false);
    	cout<<"\nthis is M*2\n";
    	M.display();
    	cout<<"\nthis is N\n";
    	N.display();

    	M*N;
    	cout<<"\nthis is M*N\n";
    	M.display();
    	cout<<"\nthis is rotating of M\n";
    	M.transposition();
    	M.display();

    	cout<<"\n\n"<<"row is:"<<M.row();
    	cout<<"\ncol is:"<<M.col()<<endl;
    	return 0;
    }

    Matrix& Matrix::transposition()
    {
    	double hold;
    	int temp;
    	for (int r =0; r< rowNum; r++)
    	{
    		for (int c=0; c< r; c++)
    		{
    			hold = lst[r][c];
    			lst[r][c] = lst[c][r];
    			lst[c][r] = hold;
    		}
    	}
    	temp = rowNum;
    	rowNum = colNum;
    	colNum = temp;
    	return (*this);
    }

    Matrix& Matrix::operator +(Matrix other)
    {
    	if (rowNum!= other.row() || colNum!= other.col())
    	{
    		cout<<"\nTwo matrix has different row or col number!\n";
    		return (*this);
    	}
    	else
    	{
    		for (int r=0; r< rowNum; r++)
    		{
    			for (int c=0; c< colNum; c++)
    			{
    				lst[r][c] +=other.items(r, c);
    			}
    		}
    		return (*this);
    	}
    }

    Matrix& Matrix::operator *(Matrix other)
    {
    	double total =0;
    	Matrix temp;
    	temp.setRow(rowNum);
    	temp.setCol(other.col());

    	if (colNum!=other.row())
    	{
    		cout<<"\nrow & col are not same!\n";

    	}
    	else
    	{
    		for (int r =0; r< rowNum; r++)
    		{
    			for (int c=0; c<other.col(); c++)
    			{
    				total =0;
    				for (int i=0; i<colNum; i++)
    				{
    					total += lst[r][i] * other.items(i, c);
    				}
    				temp.items(r, c) = total;
    			}
    		}
    		*this = temp;

    	}
    	return (*this);
    }

    Matrix& Matrix::operator =(Matrix other)
    {
    	setRow(other.row());
    	setCol(other.col());
    	for (int r=0; r< other.row(); r++)
    	{
    		for (int c=0; c< other.col(); c++)
    		{
    			lst[r][c] = other.items(r, c);
    		}
    	}

    	return (*this);
    }

    void Matrix::mul(int dest, double scalor)
    {
    	for (int c=0; c< colNum; c++)
    	{
    		lst[dest][c] *= scalor;
    	}
    }

    Matrix& Matrix::operator *(double i)
    {
    	for (int r=0; r<rowNum; r++)
    	{
    		for (int c=0; c<colNum; c++)
    		{
    			lst[r][c] *= i;
    		}
    	}
    	return (*this);
    }

    void Matrix::echelon(int r, bool reduced)
    {
    	int c=r;
    	if (r<rowNum)
    	{
    		while (c< colNum)
    		{
    			if (lst[r][c] ==0)
    			{
    				c++;
    			}
    			else
    			{
    				mul(r, 1/lst[r][c]);   //make it 1 for this row
    				for (int i=(!reduced?r+1:0); i< rowNum; i++)
    				{
    					if (i!=r)
    					{
    						mul(r, i, -lst[i][c]);
    					}
    				}
    				echelon(r+1, reduced);
    				break;
    			}
    		}
    	}

    }

    void Matrix::mul(int source, int dest, double scalor)
    {
    	for (int c=0; c< colNum; c++)
    	{
    		lst[dest][c] += lst[source][c]*scalor;
    	}
    }

    double& Matrix::items(int r, int c)
    {
    	return lst[r][c];
    }

    void Matrix::readFromFile(const char* fileName)
    {
    	int r=0, c=0;
    	char ch;
    	ifstream f;
    	f.open(fileName);
    	while (!f.eof())
    	{
    		ch = f.peek();

    		if (ch!=10)
    		{

    			f>>lst[r][c];
    			c++;
    			if (c>colNum)
    				colNum = c;
    		}
    		else
    		{
    			f.ignore();
    			r++;
    			setCol(c);
    			c =0;
    		}
    	}
    	if (r!=0)
    	{
    		setRow(r+1);
    	}
    }

    void Matrix::initialize()
    {
    	for (int r=0; r < rowNum; r++)
    	{
    		for (int c=0; c< colNum; c++)
    		{
    			lst[r][c] = r*2+c;
    		}
    	}
    }

    void Matrix::display()
    {
    //	int temp;
    	long preFlag;
    	preFlag = cout.flags();
    //	temp = cout.precision(4);
    //	cout.setf(ios::fixed);

    	cout<<"row\\col";
    	for (int c=0; c< colNum; c++)
    	{
    		cout<<"\t"<<c;
    	}
    	cout<<"\n\n";
    	for (int r = 0; r< rowNum; r++)
    	{
    		cout<<r;
    		for (c = 0; c< colNum; c++)
    		{
    			cout<<"\t"<<(fabs(lst[r][c])<LIMIT?0:lst[r][c]);
    		}
    		cout<<endl;
    	}
    //	cout.precision(temp);
    	cout.flags(preFlag);
    }

    Matrix::Matrix()
    {
    	rowNum = 5;
    	colNum = 5;
    	initialize();
    }