为了偷懒线性代数作业而写的,功能有矩阵化简(高斯消元法),解方程组(包括齐次和非齐次),求逆矩阵.
解方程的过程是模拟人算(我实在想不出其他方法)
特点是能够保存化简中每个步骤以及该步运算后的结果(方便抄).
本还想再做后续的其他功能(比如求方阵的特征值),但是太难而且线性代数的课程也结束了,做出来也用不上,就弃坑了..= =|||

补充:最近在看《Effective C++》一书,发现我在这个程序里犯了一个重大错误:没有把基类析构函数声明为virtual,原来测试时没找到原因的内存泄漏就出在这里,果然作为初学者,我还得更加努力啊~~~

//Version 0.9.3

#include
"双链表.h"
class CRESULT                //结果信息类
{
public:
    
const int** pArray;
    
const int** pTArray;
    
const int** pAArray;
    
const int iSizeY;
    
const int iSizeX;
    
const int iRankA;
    
const int iRank;
    
const int iDet;
    
const int iRoots;
    
const int** iRootsNum;
    
const int** iRootsDen;
    
const bool bHomo;
    CRESULT(
const int** pArray,const int** pTArray,const int** pAArray,const int iSizeY,const int iSizeX,const int iRankA,const int iRank,const int iDet,const int iRoots,const int** iRootsNum,const int** iRootsDen,const bool bHomo);
}
;
class CDynamicArray2D    //基类
{
protected:
    
int** pArray;            //矩阵
    int** pTArray;            //转置矩阵
public:
    
int iSizeY,iSizeX;        //行数与列数
    CDynamicArray2D(int** p,int iSizeY,int iSizeX);
    CDynamicArray2D(
int iSizeY,int iSizeX);
    CDynamicArray2D();
    
~CDynamicArray2D();
    
int fabs(int x);                                        //求绝对值

    
int** New2D();
    
void Delete2D(int** Ptr);
    
void fnTranspose();
    
void fnTransposeNew();
    
virtual CRESULT fnRunCalc();    //执行运算并输出结果

    
static int** New2D(const int iSizeY,const int iSizeX);//创建矩阵,参数为行数与列数
    static void Delete2D(int** Ptr,const int iSizeY);    //删除矩阵,参数为行数
    static void fnArrayCopy(int** const pDst,const int** const pSrc,const int iSizeY,const int iSizeX);//复制矩阵,pDst为目标矩阵,pSrc为源矩阵
    static void fnTranspose(int*** ppArr,const int iSizeY,const int iSizeX);                        //转置矩阵,参数中的行列数为原矩阵的行列数
    static int** fnTransposeNew(const int** const pArr,const int iSizeY,const int iSizeX);        //转置矩阵但不改变原矩阵,而是输出一个新矩阵
    static int fnCommonDivisor(int m,int n);                //求m,n的最大公约数
    static int fnCommonMultiple(int m,int n);                        //求m,n的最小公倍数

    CDynamicArray2D
& operator=(CDynamicArray2D &r);
}
;


class CDeterminant:public CDynamicArray2D    //行列式类
{
private:
    
int* pValue;                        //保存行列式的值
public:
    
int& iSize/*=CMatrix::iSizeX*/;        //保存行列式阶数,引用基类的列数
    CDeterminant(int** p,int iSize);
    CDeterminant(
int iSize);
    CDeterminant();
    
~CDeterminant();


    
int GetValue();                        //返回行列式的值
    int fnDeterminantCalc();
    
void fnTranspose();
    
void fnTransposeNew();
    
int** New2D();
    CRESULT fnRunCalc();

    
static int** New2D(const int iSize);                //重载基类函数,参数表中的两个关于矩阵大小的参数(行列数)改为单个(阶数)
    static int fnDeterminantCalc(const int** const pDet,const int iSize); //计算行列式的值
    static void fnDeterminantZoom(int** const pDst,const int** const pSrc,const int iPosY,const int iPosX,const int iSize);//求pSrc[iPosY][iPosX]的余子式并保存到pDst中,iSize为原阶数
    static void fnTranspose(int** const pDet,const int iSize);    
    
static int** fnTransposeNew(const int** const pDet,const int iSize);
    
static void fnArrayCopy(int** const pDst,const int** const pSrc,const int iSize);
    
static int** fnCofactor(const int** const pDet,const int iPosY,const int iPosX,const int iSize);//生成pSrc[iPosY][iPosX]的余子式并返回,iSize为原阶数
    static int fnCofactorValue(const int** const pDet,const int iPosY,const int iPosX,const int iSize);//求pSrc[iPosY][iPosX]的代数余子式的值

    
int operator+(CDeterminant &r);        //重载运算符,对行列式值进行四则运算和比较
    int operator-(CDeterminant &r);
    
int operator*(CDeterminant &r);
    
int operator/(CDeterminant &r);
    
bool operator==(CDeterminant &r);
    
bool operator!=(CDeterminant &r);
    
bool operator>(CDeterminant &r);
    
bool operator<(CDeterminant &r);
    
bool operator>=(CDeterminant &r);
    
bool operator<=(CDeterminant &r);
}
;

class CStep:public CDynamicArray2D        //运算步骤类
{
    friend 
class CMatrix;
public:
    CString strOper;
    CStep(
int** p,int iSizeY,int iSizeX,CString s,int n);
    CStep(
int n);
    CStep();
    
~CStep();
    
const int** GetArray();
    
int nIndex;

    
bool operator==(const CStep &r);
}
;

class CMatrix:public CDynamicArray2D    //矩阵类
{
protected:
    
int fnRCommonDivisor(int iR,bool min=0);                //求某行元素的最大公约数,当min=1时,-1也作为公约数
    bool fnRZeroCheck(int iR);                                //检查某行元素是否全为0
    bool fnRZeroCheck(int iR,int iX);                        //检查某行前几个元素是否全为0
    List<CStep> mylist;                                        //记录化简步骤的链表
public:
    
int iRank;                                                //秩数
    ListItr<CStep> steps;                            //链表操作器
    CMatrix(int** p,int iSizeY,int iSizeX);
    CMatrix(
int iSizeY,int iSizeX);
    CMatrix();
    
~CMatrix();

    
//初等行变换函数(Elementary Row Transformation of Matrix)
    void fnEleRowTran(int iMod,int iR,bool op=0);                //aRi,op=0时为乘,op=1时为除
    void fnEleRowTran(int iRa,int iMod,int iRb);                //Rj+aRi
    void fnEleRowTranEx(int iRa,int iRb);                        //Ri<-->Rj

    
void fnEchelon();                                    //化为梯矩阵
    virtual void fnGauss();                                                //高斯消元法
    CRESULT fnRunCalc();
    
virtual void fnAdjointNew();


    CMatrix
* operator+(CMatrix &r);                        //重载运算与,对矩阵进行四则运算和比较
    CMatrix* operator-(CMatrix &r);
    CMatrix
* operator*(int iA);
    CMatrix
* operator*(CMatrix &r);
    
bool operator==(CMatrix &r);
}
;

struct UnknownX                    //未知数信息
{
    
int iMod;
    
int iX;
}
;
class CEquationGroup:public CMatrix //方程组类
{
public:
    UnknownX
* xMain;    //主变元序列
    UnknownX* xFree;    //自由变元序列
public:
    
int iRankA;            //系数矩阵的秩数
    bool bHomo;    //1为齐次方程组,0为非齐次
    int** iRootsNum;        //解的分子
    int** iRootsDen;        //解的分母
    CEquationGroup(int** p,int iSizeY,int iSizeX);
    CEquationGroup(
int iSizeY,int iSizeX);
    CEquationGroup();
    
~CEquationGroup();
    
void fnGauss(); 
    
int fnSolve();        //解方程组,返回值表示解的情况,-1:无解,0:只有零解,1:有唯一解,>1:有无穷多个解
    CRESULT fnRunCalc();
}
;

class CSquare:public CMatrix,public CDeterminant //方阵类
{
    
int** pAArray;                        //伴随矩阵
public:
    CSquare(
int** p,int iSize);
    CSquare(
int iSize);
    CSquare();
    
~CSquare();
    
void fnAdjointNew();
    
void fnTranspose();
    
void fnTransposeNew();
    CRESULT fnRunCalc();

    
static void fnAdjoint(int** const pDet,const int iSize);                    //将pDet转化为其伴随矩阵
    static int** fnAdjointNew(const int** const pDet,const int iSize);            //生成pDet的伴随矩阵
}
;

//Version 0.9.3

#include
"stdafx.h"
#include
"DeterminantAndMatrix.h"
CDynamicArray2D::CDynamicArray2D(
int** p,int iSizeY,int iSizeX)
    : iSizeY(iSizeY)
    , iSizeX(iSizeX)
{
    pArray
=New2D();
    pTArray
=NULL;
    fnArrayCopy(pArray,(
const int**const)p,iSizeY,iSizeX);
}

CDynamicArray2D::CDynamicArray2D(
int iSizeY,int iSizeX)
    : iSizeY(iSizeY)
    , iSizeX(iSizeX)
{
    pArray
=New2D();
    pTArray
=NULL;
    
for(int y=0;y<iSizeY;y++)
        
for(int x=0;x<iSizeX;x++)
            pArray[y][x]
=0;
}

CDynamicArray2D::CDynamicArray2D()
{
    iSizeX
=iSizeY=0;
    pArray
=NULL;
    pTArray
=NULL;
}

CDynamicArray2D::
~CDynamicArray2D()
{
    
if (pTArray!=NULL)
        Delete2D(pTArray,iSizeX);
    
if (pArray!=NULL)
        Delete2D(pArray);
}

int CDynamicArray2D::fabs(int x)
{
    
return x<0?-x:x;
}

int** CDynamicArray2D::New2D()
{
    
int** pTemp=new int*[iSizeY];
    
for(int i=0;i<iSizeY;i++)
    
{
        pTemp[i]
=new int[iSizeX];
    }

    
return pTemp;
}

int** CDynamicArray2D::New2D(const int iSizeY,const int iSizeX)
{
    
int** pTemp=new int*[iSizeY];
    
for(int i=0;i<iSizeY;i++)
    
{
        pTemp[i]
=new int[iSizeX];
    }

    
return pTemp;
}

void CDynamicArray2D::Delete2D(int** Ptr)
{
    Delete2D(Ptr,iSizeY);
}

void CDynamicArray2D::Delete2D(int** Ptr,const int iSizeY)
{
    
for(int i=0;i<iSizeY;i++)
    
{
        delete []Ptr[i];
        Ptr[i]
=NULL;
    }

    delete []Ptr;
}

void CDynamicArray2D::fnArrayCopy(int** const pDst,const int** const pSrc,const int iSizeY,const int iSizeX)
{
    
for(int y=0;y<iSizeY;y++)
    
{
        
for(int x=0;x<iSizeX;x++)
        
{
            pDst[y][x]
=pSrc[y][x];
        }

    }

}

void CDynamicArray2D::fnTranspose()
{
    
if(pTArray==NULL)
        pTArray
=New2D();
    fnArrayCopy(pTArray,(
const int**const)pArray,iSizeY,iSizeX);
    fnTranspose(
&pArray,iSizeY,iSizeX);
    
int temp=iSizeY;
    iSizeY
=iSizeX;
    iSizeX
=temp;
}

void CDynamicArray2D::fnTranspose(int*** const ppArr,const int iSizeY,const int iSizeX)
{
    
int** pTempArr=fnTransposeNew((const int**const)*ppArr,iSizeY,iSizeX);
    Delete2D(
*ppArr,iSizeX);
    
*ppArr=New2D(iSizeX,iSizeY);
    fnArrayCopy(
*ppArr,(const int**const)pTempArr,iSizeX,iSizeY);
    Delete2D(pTempArr,iSizeX);
}

void CDynamicArray2D::fnTransposeNew()
{
    
if(pTArray!=NULL)
        Delete2D(pTArray,iSizeY);
    pTArray
=fnTransposeNew((const int**const)pArray,iSizeY,iSizeX);
}

int** CDynamicArray2D::fnTransposeNew(const int** const pArr,const int iSizeY,const int iSizeX)
{
    
int** pNewArr=New2D(iSizeX,iSizeY);
    
for(int y=0;y<iSizeX;y++)
    
{
        
for(int x=0;x<iSizeY;x++)
        
{
            pNewArr[y][x]
=pArr[x][y];
        }

    }

    
return pNewArr;
}

int CDynamicArray2D::fnCommonDivisor(int m,int n)
{
    
int p,r,temp;
    
if (n<m)
    
{
        temp
=n;
        n
=m;
        m
=temp;
    }

    p
=n*m;
    
while(m!=0)
    
{
        r
=n%m;
        n
=m;
        m
=r;
    }

    
return n;
}

int CDynamicArray2D::fnCommonMultiple(int m,int n)
{
    m
=m==0?1:m;
    n
=n==0?1:n;

    m
=m<0?-m:m;
    n
=n<0?-n:n;
    
    
/*int GBS;
    for(GBS=m<=n?n:m;GBS%m!=0||GBS%n!=0||GBS<=0;GBS++){}        //求最小公倍数,枚举法
    return GBS;
*/

    
    
int p,r,temp;                                                //求最小公倍数,辗转相除法
    if (n<m)
    
{
        temp
=n;
        n
=m;
        m
=temp;
    }

    p
=n*m;
    
while(m!=0)
    
{
        r
=n%m;
        n
=m;
        m
=r;
    }

    
return p/n;
}

CRESULT CDynamicArray2D::fnRunCalc()
{
    CRESULT dat((
const int**)pArray,(const int**)pTArray,NULL,iSizeY,iSizeX,0,0,0,0,NULL,NULL,0);
    
return dat;
}

CDynamicArray2D
& CDynamicArray2D::operator=(CDynamicArray2D &r)
{

    
if(r.iSizeX==0||r.iSizeY==0)
    
{
        pArray
=pTArray=NULL;
        
return *this;
    }

    
if(r.pArray!=NULL)
    
{
        
if(pArray==NULL)
            pArray
=New2D(iSizeY,iSizeX);
        fnArrayCopy(pArray,(
const int**const)r.pArray,r.iSizeY,r.iSizeX);
    }

    
else
    
{
        
if(pArray!=NULL)
            Delete2D(pArray);
        pArray
=NULL;
    }

    
if(r.pTArray!=NULL)
    
{
        
if(pTArray==NULL)
            pTArray
=New2D(r.iSizeX,r.iSizeY);
        fnArrayCopy(pTArray,(
const int**const)r.pTArray,r.iSizeX,r.iSizeY);
    }

    
else
    
{
        
if(pTArray!=NULL)
            Delete2D(pTArray,iSizeX);
        pTArray
=NULL;
    }

    iSizeY
=r.iSizeY;
    iSizeX
=r.iSizeX;
    
return *this;
}



CDeterminant::CDeterminant(
int** p,int iSize)
    : CDynamicArray2D(p,iSize,iSize)
    , iSize(CDynamicArray2D::iSizeX)
    , pValue(NULL)
{}
CDeterminant::CDeterminant(
int iSize)
    : CDynamicArray2D(iSize,iSize)
    , iSize(CDynamicArray2D::iSizeX)
    , pValue(NULL)
{}
CDeterminant::CDeterminant()
    : iSize(CDynamicArray2D::iSizeX)
    , pValue(NULL)
{}
CDeterminant::
~CDeterminant()
{
    
if (pValue!=NULL)
        delete pValue;
}

int** CDeterminant::New2D()
{
    
return CDynamicArray2D::New2D();
}

int** CDeterminant::New2D(const int iSize)
{
    
return CDynamicArray2D::New2D(iSize,iSize);
}

int CDeterminant::fnDeterminantCalc()
{
    
if (pValue==NULL)
        pValue
=new int;
    
return *pValue=fnDeterminantCalc((const int**const)pArray,iSize);
}

int CDeterminant::fnDeterminantCalc(const int** const pDet,const int iSize)
{
    
if(iSize==1)
    
{
        
return pDet[0][0];
    }

    
int iX,iResult=0;
    
for(iX=0;iX<iSize;iX++)
    
{
        iResult
+=pDet[0][iX]*fnCofactorValue(pDet,0,iX,iSize);
    }

    
return iResult;
}

void CDeterminant::fnDeterminantZoom(int** const pDst,const int** const pSrc,const int iPosY,const int iPosX,const int iSize)
{
    
int x,y;
    
for(y=0;y<iSize-1;y++)
    
{
        
for(x=0;x<iSize-1;x++)
        
{
            pDst[y][x]
=pSrc[y+(y>=iPosY)][x+(x>=iPosX)];
        }

    }

}

void CDeterminant::fnArrayCopy(int** const pDst,const int** const pSrc,const int iSize)
{
    CDynamicArray2D::fnArrayCopy(pDst,pSrc,iSize,iSize);
}

void CDeterminant::fnTranspose()
{
    
if(pTArray==NULL)
        pTArray
=New2D();
    fnArrayCopy(pTArray,(
const int**const)pArray,iSize);
    fnTranspose(pArray,iSize);
}

void CDeterminant::fnTranspose(int** const pDet,const int iSize)
{
    
int** pTempDet=fnTransposeNew((const int**const)pDet,iSize);
    fnArrayCopy(pDet,(
const int**const)pTempDet,iSize);
    Delete2D(pTempDet,iSize);
}

void CDeterminant::fnTransposeNew()
{
    CDynamicArray2D::fnTransposeNew();
}

int** CDeterminant::fnTransposeNew(const int** const pDet,const int iSize)
{
    
return CDynamicArray2D::fnTransposeNew(pDet,iSize,iSize);
}

int** CDeterminant::fnCofactor(const int** const pDet,const int iPosY,const int iPosX,const int iSize)
{
    
int** pOutDet=New2D(iSize-1);
    fnDeterminantZoom(pOutDet,pDet,iPosY,iPosX,iSize);
    
return pOutDet;
}

int CDeterminant::fnCofactorValue(const int** const pDet,const int iPosY,const int iPosX,const int iSize)
{
    
int** pTempDet=fnCofactor(pDet,iPosY,iPosX,iSize);
    
int iResult=(((iPosY+1+iPosX+1)%2==0)?1:-1)*fnDeterminantCalc((const int**const)pTempDet,iSize-1);
    Delete2D(pTempDet,iSize
-1);
    
return iResult;
}

int CDeterminant::GetValue()
{
    
return *pValue;
}

CRESULT CDeterminant::fnRunCalc()
{
    CRESULT dat((
const int**)pArray,(const int**)pTArray,NULL,iSize,iSize,0,0,*pValue,0,NULL,NULL,0);
    
return dat;
}

int CDeterminant::operator+(CDeterminant &r)
{
    
if(pValue==NULL)
    
{
        pValue
=new int;
        fnDeterminantCalc();
    }

    
if(r.pArray==NULL)
    
{
        r.pValue
=new int;
        r.fnDeterminantCalc();
    }

    
return *pValue+(*(r.pValue));
}

int CDeterminant::operator-(CDeterminant &r)
{
    
if(pValue==NULL)
    
{
        pValue
=new int;
        fnDeterminantCalc();
    }

    
if(r.pArray==NULL)
    
{
        r.pValue
=new int;
        r.fnDeterminantCalc();
    }

    
return *pValue-(*(r.pValue));
}

int CDeterminant::operator*(CDeterminant &r)
{
    
if(pValue==NULL)
    
{
        pValue
=new int;
        fnDeterminantCalc();
    }

    
if(r.pArray==NULL)
    
{
        r.pValue
=new int;
        r.fnDeterminantCalc();
    }

    
return *pValue*(*(r.pValue));
}

int CDeterminant::operator/(CDeterminant &r)
{
    
if(pValue==NULL)
    
{
        pValue
=new int;
        fnDeterminantCalc();
    }

    
if(r.pArray==NULL)
    
{
        r.pValue
=new int;
        r.fnDeterminantCalc();
    }

    
return *pValue/(*(r.pValue));
}

bool CDeterminant::operator==(CDeterminant &r)
{
    
if(pValue==NULL)
    
{
        pValue
=new int;
        fnDeterminantCalc();
    }

    
if(r.pArray==NULL)
    
{
        r.pValue
=new int;
        r.fnDeterminantCalc();
    }

    
return *pValue==(*(r.pValue));
}

bool CDeterminant::operator!=(CDeterminant &r)
{
    
if(pValue==NULL)
    
{
        pValue
=new int;
        fnDeterminantCalc();
    }

    
if(r.pArray==NULL)
    
{
        r.pValue
=new int;
        r.fnDeterminantCalc();
    }

    
return *pValue!=(*(r.pValue));
}

bool CDeterminant::operator>(CDeterminant &r)
{
    
if(pValue==NULL)
    
{
        pValue
=new int;
        fnDeterminantCalc();
    }

    
if(r.pArray==NULL)
    
{
        r.pValue
=new int;
        r.fnDeterminantCalc();
    }

    
return *pValue>(*(r.pValue));
}

bool CDeterminant::operator<(CDeterminant &r)
{
    
if(pValue==NULL)
    
{
        pValue
=new int;
        fnDeterminantCalc();
    }

    
if(r.pArray==NULL)
    
{
        r.pValue
=new int;
        r.fnDeterminantCalc();
    }

    
return *pValue<(*(r.pValue));
}

bool CDeterminant::operator>=(CDeterminant &r)
{
    
if(pValue==NULL)
    
{
        pValue
=new int;
        fnDeterminantCalc();
    }

    
if(r.pArray==NULL)
    
{
        r.pValue
=new int;
        r.fnDeterminantCalc();
    }

    
return *pValue>=(*(r.pValue));
}

bool CDeterminant::operator<=(CDeterminant &r)
{
    
if(pValue==NULL)
    
{
        pValue
=new int;
        fnDeterminantCalc();
    }

    
if(r.pArray==NULL)
    
{
        r.pValue
=new int;
        r.fnDeterminantCalc();
    }

    
return *pValue<=(*(r.pValue));
}



CStep::CStep(
int** p,int iSizeY,int iSizeX,CString s,int n)
    : CDynamicArray2D(p,iSizeY,iSizeX)
    , strOper(s)
    , nIndex(n)
{}
CStep::CStep(
int n)
    : strOper(
"")
    , nIndex(n)
{}
CStep::CStep()
    : strOper(
"")
    , nIndex(
-1){}
CStep::
~CStep(){}
const int** CStep::GetArray()
{
    
return (const int**)pArray;
}

bool CStep::operator==(const CStep &r)
{
    
return nIndex==r.nIndex;
}

CMatrix::CMatrix(
int** p,int iSizeY,int iSizeX)
    : CDynamicArray2D(p,iSizeY,iSizeX)
    , iRank(iSizeY)
    , steps(mylist)
{}
CMatrix::CMatrix(
int iSizeY,int iSizeX)
    :CDynamicArray2D(iSizeY,iSizeX)
    , iRank(iSizeY)
    , steps(mylist)
{}
CMatrix::CMatrix()
    : iRank(
0)
    , steps(mylist)
{}
CMatrix::
~CMatrix(){}
int CMatrix::fnRCommonDivisor(int iR,bool min/*=0*/)
{
    
int GYS=1;
    
for(int x=0;x<iSizeX;x++)
    
{
        
if (pArray[iR][x]!=0)
        
{
            GYS
=fabs(pArray[iR][x]);
            
break;
        }

    }

    
for(int x=1;x<iSizeX;x++)
        
if (GYS>fabs(pArray[iR][x])&&pArray[iR][x]!=0)
            GYS
=fabs(pArray[iR][x]);
    
for(int x=0;x<iSizeX;x++)
    
{
        
if ((fabs(pArray[iR][x]))%GYS!=0)
        
{
            x
=0;
            GYS
--;
        }

    }

    
if(min)
    
{
        
int x;
        
for(x=0;x<iSizeX;x++)
        
{
            
if (pArray[iR][x]>0)
                
break;
        }

        
if (x==iSizeX&&!fnRZeroCheck(iR))
            GYS
*=-1;
    }

    
return GYS;
}

bool CMatrix::fnRZeroCheck(int iR)
{
    
for(int x=0;x<iSizeX;x++)
    
{
        
if (pArray[iR][x]!=0)
            
return 0;
    }

    
return 1;
}

bool CMatrix::fnRZeroCheck(int iR,int iX)
{
    
for(int x=0;x<=iX;x++)
    
{
        
if (pArray[iR][x]!=0)
            
return 0;
    }

    
return 1;
}

void CMatrix::fnEleRowTran(int iMod,int iR,bool op/*=0*/)
{
    
if (iMod==1||iMod==0)
        
return;
    
if (iMod==-1)
        op
=0;
    CString temp;
    
for(int x=0;x<iSizeX;x++)
    
{
        
if(!op)
            pArray[iR][x]
*=iMod;
        
else
            pArray[iR][x]
/=iMod;
    }

    
if(!op)
        temp.AppendFormat(_T(
"%d*R%d"),iMod,iR+1);
    
else if (iMod<0)
    
{
        iMod
*=-1;
        temp.AppendFormat(_T(
"-(1/%d)*R%d"),iMod,iR+1);
    }

    
else
        temp.AppendFormat(_T(
"(1/%d)*R%d"),iMod,iR+1);
    CStep step(pArray,iSizeY,iSizeX,temp,steps.Count()
+1);
    steps
+step;
    step.pArray
=NULL;
}

void CMatrix::fnEleRowTran(int iRa,int iMod,int iRb)
{
    
if (iMod==0)
        
return;
    
for(int x=0;x<iSizeX;x++)
        pArray[iRa][x]
+=iMod*pArray[iRb][x];
    CString temp;
    
if (iMod>=0)
    
{
        
if (iMod==1)
            temp.AppendFormat(_T(
"R%d+R%d"),iRa+1,iRb+1);
        
else
            temp.AppendFormat(_T(
"R%d+%d*R%d"),iRa+1,iMod,iRb+1);
    }

    
else
    
{
        
if (iMod==-1)
            temp.AppendFormat(_T(
"R%d-R%d"),iRa+1,iRb+1);
        
else
            temp.AppendFormat(_T(
"R%d%d*R%d"),iRa+1,iMod,iRb+1);
    }

    CStep step(pArray,iSizeY,iSizeX,temp,steps.Count()
+1);
    steps
+step;
    step.pArray
=NULL;
}

void CMatrix::fnEleRowTranEx(int iRa,int iRb)
{
    
if (iRa==iRb)
        
return;
    
int* temparr=new int[iSizeX];
    
for(int x=0;x<iSizeX;x++)
        temparr[x]
=pArray[iRa][x];
    
for(int x=0;x<iSizeX;x++)
        pArray[iRa][x]
=pArray[iRb][x];
    
for(int x=0;x<iSizeX;x++)
        pArray[iRb][x]
=temparr[x];
    delete []temparr;
    CString temp;
    temp.AppendFormat(_T(
"R%d<-->R%d"),iRa+1,iRb+1);
    CStep step(pArray,iSizeY,iSizeX,temp,steps.Count()
+1);
    steps
+step;
    step.pArray
=NULL;
}

void CMatrix::fnEchelon()
{
    steps.MakeEmpty(mylist);
    
for(int c=0;c<iSizeX&&c<iRank;c++)
    
{
        
for(int y=0;y<iRank;y++)
        
{
            
if(fnRZeroCheck(y,c))
            
{
                
for(int r=iRank-1;r>y;r--)
                
{
                    
if (!fnRZeroCheck(r,c))
                    
{
                        fnEleRowTranEx(y,r);
                        
if (fnRZeroCheck(r))
                            iRank
--;
                        
break;
                    }

                }

            }

        }

        
for(int y=0;y<iRank;y++)
            fnEleRowTran(fnRCommonDivisor(y),y,(
bool)1);
        
if (pArray[c][c]==0)
            
continue;
        
if(pArray[c][c]!=1&&pArray[c][c]!=-1)
        
{
            
for(int r=c+1;r<iRank;r++)
            
{
                
if (pArray[r][c]==0)
                    
continue;
                
if ((pArray[c][c]-1)%pArray[r][c]==0)
                
{
                    
int mod=-(pArray[c][c]-1)/pArray[r][c];
                    fnEleRowTran(c,mod,r);
                    
break;
                }

                
else if ((pArray[c][c]+1)%pArray[r][c]==0)
                
{
                    
int mod=-(pArray[c][c]+1)/pArray[r][c];
                    fnEleRowTran(c,mod,r);
                    fnEleRowTran(
-1,c);
                    
break;
                }

            }

        }

        
for(int r=c+1;r<iRank;r++)
        
{
            
if (pArray[r][c]==0)
                
continue;
            
int cm=fnCommonMultiple(pArray[c][c],pArray[r][c]);
            
if (pArray[r][c]<0)
                cm
=-cm;
            fnEleRowTran(cm
/pArray[r][c],r);
            fnEleRowTran(r,
-pArray[r][c]/pArray[c][c],c);
        }

        
for(int y=iRank-1;y>-1;y--)
        
{
            
bool bt=fnRZeroCheck(y);
            
if(fnRZeroCheck(y))
            
{
                
for(int r=iRank-1;r>y;r--)
                
{
                    
if (!fnRZeroCheck(r))
                    
{
                        fnEleRowTranEx(y,r);
                        
break;
                    }

                }

                iRank
--;
            }

        }

    }

    
for(int y=0;y<iRank-1;y++)
    
{
        
int x1,x2;
        
for(x1=0;x1<iSizeX;x1++)
        
{
            
if(pArray[y][x1]!=0)
                
break;
        }

        
for(x2=0;x2<iSizeX;x2++)
        
{
            
if(pArray[y+1][x2]!=0)
                
break;
        }

        
if(x1==x2)
        
{
            
int c=x1;
            
int cm=fnCommonMultiple(pArray[y][c],pArray[y+1][c]);
            
if (pArray[y+1][c]<0)
                cm
=-cm;
            fnEleRowTran(cm
/pArray[y+1][c],y+1);
            fnEleRowTran(y
+1,-pArray[y+1][c]/pArray[y][c],y);
        }

    }

    
for(int y=0;y<iRank;y++)
    
{
        
if(fnRZeroCheck(y))
            iRank
--;
    }

    
for(int y=0;y<iRank;y++)
        fnEleRowTran(fnRCommonDivisor(y),y,(
bool)1);
}

void CMatrix::fnGauss()
{
    fnEchelon();
    
    
for(int x=iSizeX-1;x>-1;x--)
    
{
        
int y;
        
for(y=iRank-1;y>0;y--)
        
{
            
if(pArray[y][x]!=0)
                
break;
        }

        
if(y==0)
            
continue;
        
for(int r=y-1;r>-1;r--)
        
{
            
if(pArray[r][x]==0)
                
continue;
            
int cm=fnCommonMultiple(pArray[y][x],pArray[r][x]);
            
if (pArray[r][x]<0)
                cm
=-cm;
            fnEleRowTran(cm
/pArray[r][x],r);
            fnEleRowTran(r,
-pArray[r][x]/pArray[y][x],y);
        }

        
for(int y=0;y<iRank-1;y++)
        
{
            
int x1,x2;
            
for(x1=0;x1<iSizeX;x1++)
            
{
                
if(pArray[y][x1]!=0)
                    
break;
            }

            
for(x2=0;x2<iSizeX;x2++)
            
{
                
if(pArray[y+1][x2]!=0)
                    
break;
            }

            
if(x1>x2)
                fnEleRowTranEx(y,y
+1);
        }

        
for(int y=0;y<iRank;y++)
            fnEleRowTran(fnRCommonDivisor(y,(
bool)1),y,(bool)1);
    }

    
/*
    for(int r=1;r<iRank;r++)
    {
        for(int y=0;y<iRank;y++)
            fnEleRowTran(fnRCommonDivisor(y),y,(bool)1);
        if (pArray[r][r]==0)
            continue;
        for(int y=r-1;y>-1;y--)
        {
            if (pArray[y][r]==0)
                continue;
            int cm=fnCommonMultiple(pArray[r][r],pArray[y][r]);
            if (pArray[y][r]<0)
                cm=-cm;
            fnEleRowTran(cm/pArray[y][r],y);
            fnEleRowTran(y,-pArray[y][r]/pArray[r][r],r);
        }
        for(int y=iRank-1;y>-1;y--)
        {
            bool bt=fnRZeroCheck(y);
            if(fnRZeroCheck(y))
            {
                for(int r=iRank-1;r>y;r--)
                {
                    if (!fnRZeroCheck(r))
                    {
                        fnEleRowTranEx(y,r);
                        break;
                    }
                }
                iRank--;
            }
        }
        for(int y=0;y<iRank-1;y++)
        {
            int x1,x2;
            for(x1=0;x1<iSizeX;x1++)
            {
                if(pArray[y][x1]!=0)
                    break;
            }
            for(x2=0;x2<iSizeX;x2++)
            {
                if(pArray[y+1][x2]!=0)
                    break;
            }
            if(x1>x2)
                fnEleRowTranEx(y,y+1);
        }
    }    
    for(int y=0;y<iRank;y++)
        fnEleRowTran(fnRCommonDivisor(y),y,(bool)1);
*/

}

CMatrix
* CMatrix::operator+(CMatrix &r)
{
    
if(iSizeY!=r.iSizeY||iSizeX!=r.iSizeX)
        
return NULL;
    CMatrix
* pOutMatrix=new CMatrix(iSizeY,iSizeX);
    
for(int y=0;y<iSizeY;y++)
    
{
        
for(int x=0;x<iSizeX;x++)
        
{
            pOutMatrix
->pArray[y][x]=pArray[y][x]+r.pArray[y][x];
        }

    }

    
return pOutMatrix;
}

CMatrix
* CMatrix::operator-(CMatrix &r)
{
    
if(iSizeY!=r.iSizeY||iSizeX!=r.iSizeX)
        
return NULL;
    CMatrix
* pOutMatrix=new CMatrix(iSizeY,iSizeX);
    
for(int y=0;y<iSizeY;y++)
    
{
        
for(int x=0;x<iSizeX;x++)
        
{
            pOutMatrix
->pArray[y][x]=pArray[y][x]-r.pArray[y][x];
        }

    }

    
return pOutMatrix;
}

CMatrix
* CMatrix::operator*(int iA)
{
    CMatrix
* pOutMatrix=new CMatrix(iSizeY,iSizeX);
    
for(int y=0;y<iSizeY;y++)
        
for(int x=0;x<iSizeX;x++)
            pOutMatrix
->pArray[y][x]=iA*pArray[y][x];
    
return pOutMatrix;
}

CMatrix
* CMatrix::operator*(CMatrix &r)
{
    
if(iSizeX!=r.iSizeY)
        
return NULL;
    CMatrix
* pOutMatrix=new CMatrix(iSizeY,r.iSizeX);
    
for(int y=0;y<pOutMatrix->iSizeY;y++)
    
{
        
for(int x=0;x<pOutMatrix->iSizeX;x++)
        
{
            
for(int i=0;i<iSizeX;i++)
                pOutMatrix
->pArray[y][x]+=pArray[y][i]*r.pArray[i][x];
        }

    }

    
return pOutMatrix;
}

bool CMatrix::operator==(CMatrix &r)
{
    
if(iSizeY!=r.iSizeY||iSizeX!=r.iSizeX)
        
return 0;
    
for(int y=0;y<iSizeY;y++)
        
for(int x=0;x<iSizeX;x++)
            
if(pArray[y][x]!=r.pArray[y][x])
                
return 0;
    
return 1;
}

CRESULT CMatrix::fnRunCalc()
{
    fnGauss();
    CRESULT dat((
const int**)pArray,(const int**)pTArray,NULL,iSizeY,iSizeX,iRank,iRank,0,0,NULL,NULL,0);
    
return dat;
}

void CMatrix::fnAdjointNew(){};



CEquationGroup::CEquationGroup(
int** p,int iSizeY,int iSizeX)
    : CMatrix(p,iSizeY,iSizeX)
    , iRankA(CMatrix::iRank)
    , iRootsNum(NULL)
    , iRootsDen(NULL)
    , xMain(NULL)
    , xFree(NULL)
{}
CEquationGroup::CEquationGroup(
int iSizeY,int iSizeX)
    : CMatrix(iSizeY,iSizeX)
    , iRankA(CMatrix::iRank)
    , iRootsNum(NULL)
    , iRootsDen(NULL)
    , xMain(NULL)
    , xFree(NULL)
{}
CEquationGroup::CEquationGroup()
    : iRankA(
0)
    , iRootsNum(NULL)
    , iRootsDen(NULL)
    , xMain(NULL)
    , xFree(NULL)
{}
CEquationGroup::
~CEquationGroup()
{
    
if(iRootsNum!=NULL)
        Delete2D(iRootsNum,iSizeX
-1);
    
if(iRootsDen!=NULL)
        Delete2D(iRootsDen,iSizeX
-1);
    
if(xMain!=NULL)
        delete []xMain;
    
if(xFree!=NULL)
        delete []xFree;
}

void CEquationGroup::fnGauss()
{
    CMatrix::fnGauss();
    iRankA
=iRank;
    
for(int y=0;y<iRank;y++)
        
if(fnRZeroCheck(y,iSizeX-2))
            iRankA
--;
}

int CEquationGroup::fnSolve()
{    //判断是否为齐次方程
    int y=0;
    
for(;y<iRank;y++)
    
{
        
if(pArray[y][iSizeX-1]!=0)
            
break;
    }

    
if(y==iRank)
        bHomo
=1;
    
else
        bHomo
=0;
    
//非齐次,有唯一解的情况
    if(!bHomo&&iRankA==iSizeX-1&&iRank==iSizeX-1)
    
{
        iRootsNum
=New2D(iSizeX-1,1);
        iRootsDen
=New2D(iSizeX-1,1);
        
for(int root=0;root<iSizeX-1;root++)
        
{
            
int iCD=fnCommonDivisor(pArray[root][root],pArray[root][iSizeX-1]);
            iRootsDen[root][
1]=pArray[root][root]/iCD;
            iRootsNum[root][
1]=pArray[root][iSizeX-1]/iCD;
            
if(iRootsDen[root][1]<0)
            
{
                iRootsDen[root][
1]*=-1;
                iRootsNum[root][
1]*=-1;
            }

        }

        
return 1;
    }

    
//非齐次,无解的情况
    if(!bHomo&&iRankA<iRank)
        
return -1;
    
//齐次,只有零解的情况
    if(bHomo&&iRankA==iSizeX-1)
        
return 0;
    
//统计主变元与自由变元的位置
    if(iRankA!=0)
    
{
        xMain
=new UnknownX[iRankA];
        xFree
=new UnknownX[iSizeX-1-iRankA];
        
int iCountM=-1;
        
int iCountF=-1;
        
for(int x=0;x<iSizeX-1;x++)
        
{
            
int y=0;
            
bool logic=0;
            
for(;y<iRankA;y++)
            
{
                
if(y==iCountM+1)
                
{
                    
if(pArray[y][x]!=0)
                        logic
=1;
                    
continue;
                }

                
if(pArray[y][x]!=0)
                    
break;
            }

            
if(y==iRankA&&logic)
            
{
                
++iCountM;
                xMain[iCountM].iX
=x;
                xMain[iCountM].iMod
=pArray[iCountM][x];
            }

            
else
            
{
                
++iCountF;
                xFree[iCountF].iX
=x;
                xFree[iCountF].iMod
=0;
            }

        }

    }

    
//齐次,有无穷多个解的情况
    if(bHomo&&iRankA<iSizeX-1)
    
{
        iRootsNum
=New2D(iSizeX-1,iSizeX-1-iRankA);
        
for(int y=0;y<iSizeX-1;y++)
            
for(int x=0;x<iSizeX-1-iRankA;x++)
                iRootsNum[y][x]
=0;
        iRootsDen
=New2D(iSizeX-1,iSizeX-1-iRankA);
        
for(int y=0;y<iSizeX-1;y++)
            
for(int x=0;x<iSizeX-1-iRankA;x++)
                iRootsDen[y][x]
=1;
        
for(int xf=0;xf<iSizeX-1-iRankA;xf++)
        
{
            iRootsNum[xFree[xf].iX][xf]
=1;
            
for(int xm=0;xm<iRankA;xm++)
            
{
                iRootsNum[xMain[xm].iX][xf]
=-pArray[xm][xFree[xf].iX];
                iRootsDen[xMain[xm].iX][xf]
=xMain[xm].iMod;
                
int iCD=fnCommonDivisor(iRootsNum[xMain[xm].iX][xf],iRootsDen[xMain[xm].iX][xf]);
                iRootsNum[xMain[xm].iX][xf]
/=iCD;
                iRootsDen[xMain[xm].iX][xf]
/=iCD;
                
if(iRootsDen[xMain[xm].iX][xf]<0)
                
{
                    iRootsDen[xMain[xm].iX][xf]
*=-1;
                    iRootsNum[xMain[xm].iX][xf]
*=-1;
                }

            }

        }

        
return iSizeX-1-iRankA;
    }

    
//非齐次,有无穷多个解的情况
    if(!bHomo&&iRank==iRankA&&iRankA<iSizeX-1)
    
{
        
//求通解
        iRootsNum=New2D(iSizeX-1,iSizeX-iRankA);
        
for(int y=0;y<iSizeX-1;y++)
            
for(int x=0;x<iSizeX-iRankA;x++)
                iRootsNum[y][x]
=0;
        iRootsDen
=New2D(iSizeX-1,iSizeX-iRankA);
        
for(int y=0;y<iSizeX-1;y++)
            
for(int x=0;x<iSizeX-iRankA;x++)
                iRootsDen[y][x]
=1;
        
for(int xf=0;xf<iSizeX-1-iRankA;xf++)
        
{
            iRootsNum[xFree[xf].iX][xf]
=1;
            
for(int xm=0;xm<iRankA;xm++)
            
{
                iRootsNum[xMain[xm].iX][xf]
=-pArray[xm][xFree[xf].iX];
                iRootsDen[xMain[xm].iX][xf]
=xMain[xm].iMod;
                
int iCD=fnCommonDivisor(iRootsNum[xMain[xm].iX][xf],iRootsDen[xMain[xm].iX][xf]);
                iRootsNum[xMain[xm].iX][xf]
/=iCD;
                iRootsDen[xMain[xm].iX][xf]
/=iCD;
                
if(iRootsDen[xMain[xm].iX][xf]<0)
                
{
                    iRootsDen[xMain[xm].iX][xf]
*=-1;
                    iRootsNum[xMain[xm].iX][xf]
*=-1;
                }

            }

        }

        
//求一特解
        for(int xm=0;xm<iRankA;xm++)
        
{
            iRootsNum[xMain[xm].iX][iSizeX
-iRankA-1]=pArray[xm][iSizeX-1];
            iRootsDen[xMain[xm].iX][iSizeX
-iRankA-1]=xMain[xm].iMod;
            
int iCD=fnCommonDivisor(iRootsNum[xMain[xm].iX][iSizeX-iRankA-1],iRootsDen[xMain[xm].iX][iSizeX-iRankA-1]);
            iRootsNum[xMain[xm].iX][iSizeX
-iRankA-1]/=iCD;
            iRootsDen[xMain[xm].iX][iSizeX
-iRankA-1]/=iCD;
            
if(iRootsDen[xMain[xm].iX][iSizeX-iRankA-1]<0)
            
{
                iRootsDen[xMain[xm].iX][iSizeX
-iRankA-1]*=-1;
                iRootsNum[xMain[xm].iX][iSizeX
-iRankA-1]*=-1;
            }

        }

        
return iSizeX-iRankA;
    }

    
return -1;
}

CRESULT CEquationGroup::fnRunCalc()
{
    fnGauss();
    
int roots=fnSolve();
    CRESULT dat((
const int**)pArray,(const int**)pTArray,NULL,iSizeY,iSizeX,iRankA,iRank,0,roots,(const int**)iRootsNum,(const int**)iRootsDen,bHomo);
    
return dat;
}




CSquare::CSquare(
int** p,int iSize)
    : CDeterminant(p,iSize)
    , pAArray(NULL)
{
    CMatrix::pArray
=CDeterminant::pArray;
    CMatrix::iSizeX
=CMatrix::iSizeY=CMatrix::iRank=iSize;

}

CSquare::CSquare(
int iSize)
    : CDeterminant(iSize)
    , pAArray(NULL)
{
    CMatrix::pArray
=CDeterminant::pArray;
    CMatrix::iSizeX
=CMatrix::iSizeY=CMatrix::iRank=iSize;
}

CSquare::CSquare()
    : pAArray(NULL)
{}
CSquare::
~CSquare()
{
    
if (pAArray!=NULL)
        CDeterminant::Delete2D(pAArray);
}

void CSquare::fnAdjoint(int** const pDet,const int iSize)
{
    
if(fnDeterminantCalc((const int**const)pDet,iSize)==0)
        
return;
    
int** pTempDet=CDeterminant::New2D(iSize);
    CDeterminant::fnArrayCopy(pTempDet,(
const int**const)pDet,iSize);
    
for(int y=0;y<iSize;y++)
    
{
        
for(int x=0;x<iSize;x++)
        
{
            pDet[y][x]
=fnCofactorValue((const int**const)pTempDet,y,x,iSize);
        }

    }

    CDeterminant::fnTranspose(pDet,iSize);
    CDeterminant::Delete2D(pTempDet,iSize);
}

int** CSquare::fnAdjointNew(const int** const pDet,const int iSize)
{
    
int** pOutDet=CDeterminant::New2D(iSize);
    CDeterminant::fnArrayCopy(pOutDet,pDet,iSize);
    fnAdjoint(pOutDet,iSize);
    
return pOutDet;
}

void CSquare::fnAdjointNew()
{
    
if(pAArray==NULL)
        pAArray
=CDeterminant::New2D();
    CDeterminant::fnArrayCopy(pAArray,(
const int**const)CDeterminant::pArray,iSize);
    fnAdjoint(pAArray,iSize);
}

void CSquare::fnTranspose()
{
    CDeterminant::fnTranspose();
    CMatrix::pArray
=CDeterminant::pArray;
    CMatrix::pTArray
=CDeterminant::pTArray;
}

void CSquare::fnTransposeNew()
{
    CDeterminant::fnTransposeNew();
    CMatrix::pTArray
=CDeterminant::pTArray;
}

CRESULT CSquare::fnRunCalc()
{
    fnDeterminantCalc();
    fnAdjointNew();
    fnGauss();
    CRESULT dat((
const int**)CDeterminant::pArray,(const int**)CDeterminant::pTArray,(const int**)pAArray,iSize,iSize,iRank,iRank,GetValue(),0,NULL,NULL,0);
    
return dat;
}



CRESULT::CRESULT(
const int** pArray,const int** pTArray,const int** pAArray,const int iSizeY,const int iSizeX,const int iRankA,const int iRank,const int iDet,const int iRoots,const int** iRootsNum,const int** iRootsDen,const bool bHomo)
    : pArray(pArray)
    , pTArray(pTArray)
    , pAArray(pAArray)
    , iSizeY(iSizeY)
    , iSizeX(iSizeX)
    , iRankA(iRankA)
    , iRank(iRank)
    , iDet(iDet)
    , iRoots(iRoots)
    , iRootsNum(iRootsNum)
    , iRootsDen(iRootsDen)
    , bHomo(bHomo)
{}
完整的代码,包括一个MFC窗口程序和那个没贴出来的"双链表.h"
/Files/takamachi660/矩阵计算器v0.9.3beta.rar
posted on 2009-08-05 23:06  高町⑥⑥○  阅读(2163)  评论(3编辑  收藏  举报