将矩阵逐步化简至行最简形并求秩

将矩阵逐步化简至行最简形并求秩

将矩阵逐步化简至行最简形并求秩

支持分数,显示步骤,9x9以内矩阵。

【注意】:由于实时录入字符,请务必用【英文输入法】,且用空格代替回车,【输矩阵时不要按回车(输行列数时可以)】,输错请重新运行程序。

截图:

在这里插入图片描述
在这里插入图片描述

/************************
@author:citrus
@date:2021/1/11
*************************/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define N 9
int isPrime(int x);
int m=-1,n=-1;
typedef struct fraction
{
    int numerator;
    int denominator;
}Fraction;

Fraction reduce(Fraction f)
{
    if(f.numerator==0)
    {
        f.denominator=1;
        return f;
    }
    else if(f.denominator!=0)
    {
        int sign=f.numerator/abs(f.numerator);
        f.numerator=abs(f.numerator);
        int gcd=1;
        for(int i=2;i<=(f.numerator<f.denominator?f.numerator:f.denominator);i++)
        {
            if(f.numerator%i==0&&f.denominator%i==0)gcd=i;
        }
        f.numerator=f.numerator/gcd*sign;
        f.denominator=f.denominator/gcd;
        return f;
    }
}

Fraction plus(Fraction f1,Fraction f2)
{
    Fraction f3={f1.numerator*f2.denominator+f1.denominator*f2.numerator,f1.denominator*f2.denominator};
    return reduce(f3);
}

Fraction minus(Fraction f1,Fraction f2)
{
    Fraction f3={f1.numerator*f2.denominator-f1.denominator*f2.numerator,f1.denominator*f2.denominator};
    return reduce(f3);
}

Fraction time(Fraction f1,Fraction f2)
{
    Fraction f3={f1.numerator*f2.numerator,f1.denominator*f2.denominator};
    return reduce(f3);
}

Fraction divide(Fraction f1,Fraction f2)
{
    int sign=f2.numerator/abs(f2.numerator);
    Fraction f3={f1.numerator*f2.denominator*sign,f1.denominator*abs(f2.numerator)};
    return reduce(f3);
}

Fraction reciprocal(Fraction f)
{
    if(f.numerator!=0&&f.denominator!=0)
    {
        int sign=f.numerator/abs(f.numerator);
        Fraction f0={f.denominator*sign,abs(f.numerator)};
        return reduce(f0);
    }
}

Fraction absolution(Fraction f)
{
    Fraction f0=f;
    f0.numerator=abs(f0.numerator);
    return reduce(f0);
}

int isPrime(int x)
{
    if(x>=-1&&x<=1)return 0;
    x=abs(x);
    for(int i=2;i<x;i++)
    {
        if(x%i==0)return 0;
    }
    return 1;

}

void initMartrix(Fraction mar[][N])
{
    for(int i=0;i<N;i++)
    {
        for(int j=0;j<N;j++)
        {
            mar[i][j].numerator=0;
            mar[i][j].denominator=1;
        }
    }
}
void printMartrix(Fraction mar[][N],char *str)
{
    printf("%s ==================================================\n",str);
    for(int i=0;i<m;i++)
    {
        printf("\n");
        for(int j=0;j<n;j++)
        {
            if(mar[i][j].denominator==1)printf("%4d   ",mar[i][j].numerator);
            else printf("%3d/%-2d ",mar[i][j].numerator,mar[i][j].denominator);
        }
        printf("\n");
    }
    puts("");
}

void printFullMartrix(Fraction mar[][N],char *str)
{
    printf("%s ==================================================\n",str);
    for(int i=0;i<m;i++)
    {
        printf("\n");
        for(int j=0;j<n;j++)
        {
            printf("%3d/%-2d ",mar[i][j].numerator,mar[i][j].denominator);
        }
        printf("\n");
    }
    puts("");
}

void inputMartrix(Fraction mar[][N])
{
    printf("请输入%d×%d矩阵(支持分数,仅以一空格隔开,不用回车,[实时录入],自动结束,请勿输错,请先切换至EngIME,如-12/5 7 2/3 ):\n",m,n);
    int t=0;
    int sign=1;
    int tofm=0;
    int p=1;
    int shouldentercount;
    int entercount=0;
    while(p<=m*n)
    {
        shouldentercount=(p-1)/n;
        if(entercount==shouldentercount)
        {
            puts("");
            entercount++;
        }
        char c=getche();
        if(c=='-')
        {
           sign=-1;
        }
        else if(c>='0'&&c<='9')
        {
            t=t*10+c-'0';
        }
        else if(c=='/')
        {
            mar[(p-1)/n][(p-1)%n].numerator=sign*t;
            t=0;
            sign=1;
            tofm=1;
        }
        else if(c==' ')
        {
            if(tofm==1)
            {
             mar[(p-1)/n][(p-1)%n].denominator=sign*t;
            }
            else
            {
            mar[(p-1)/n][(p-1)%n].numerator=sign*t;
            }
            t=0;
            sign=1;
            tofm=0;
            p++;
        }
        else if(c==-95||c==-94)
        {
            puts("\n错误,请结束并切换至EngIME.");
        }
    }
}

void ktimesRowi(Fraction mar[][N],int k,int i)
{
    if(i>=1&&i<=m&&k!=0)
    {
        i--;
        Fraction f={k,1};
        for(int x=0;x<n;x++)
        {
            mar[i][x]=time(mar[i][x],f);
        }
    }
}

void FractionktimesRowi(Fraction mar[][N],Fraction k,int i)
{
    if(i>=1&&i<=m)
    {
        i--;
        for(int x=0;x<n;x++)
        {
            mar[i][x]=time(mar[i][x],k);
        }
    }
}

void simplifyRowi(Fraction mar[][N],int i)
{
    if(i>=1&&i<=m)
    {
        i--;
        Fraction reciprocalOfNonZeroFirstElem;
        int gotNZFE=0;
        int printed=0;
        for(int x=0;x<n;x++)
        {
            if(mar[i][x].numerator!=0)
            {
                    if(gotNZFE==0)
                    {
                        gotNZFE=1;
                        reciprocalOfNonZeroFirstElem=reciprocal(mar[i][x]);
                    }
                    if(gotNZFE==1)
                    {
                        if(!(reciprocalOfNonZeroFirstElem.numerator==1&&reciprocalOfNonZeroFirstElem.denominator==1))
                        {
                            if(printed==0)
                            {
                                if(reciprocalOfNonZeroFirstElem.denominator==1&&reciprocalOfNonZeroFirstElem.numerator>0)
                                    printf("r%d × %d",i+1,reciprocalOfNonZeroFirstElem.numerator);
                                else if(reciprocalOfNonZeroFirstElem.denominator==1&&reciprocalOfNonZeroFirstElem.numerator<0)
                                    printf("r%d × (%d)",i+1,reciprocalOfNonZeroFirstElem.numerator);
                                else if(reciprocalOfNonZeroFirstElem.denominator!=1&&reciprocalOfNonZeroFirstElem.numerator>0)
                                    printf("r%d × %d/%d",i+1,reciprocalOfNonZeroFirstElem.numerator,reciprocalOfNonZeroFirstElem.denominator);
                                else if(reciprocalOfNonZeroFirstElem.denominator!=1&&reciprocalOfNonZeroFirstElem.numerator<0)
                                    printf("r%d × (%d/%d)",i+1,reciprocalOfNonZeroFirstElem.numerator,reciprocalOfNonZeroFirstElem.denominator);
                                printed=1;
                            }
                            mar[i][x]=time(mar[i][x],reciprocalOfNonZeroFirstElem);
                        }
                    }
            }
        }
        if(printed==1)printMartrix(mar,"");
    }
}

void RowiminusRowj(Fraction mar[][N],int i,int j)
{
    if(i>=1&&i<=m&&j>=1&&j<=m)
    {
        printf("r%d - r%d",i,j);
        i--;j--;
        for(int x=0;x<n;x++)
        {
            mar[i][x]=minus(mar[i][x],mar[j][x]);
        }
        printMartrix(mar,"");
    }
}

void RowiminusFractionkRowj(Fraction mar[][N],int i,int j,Fraction f){
    if(i>=1&&i<=m&&j>=1&&j<=m)
    {
        if(f.denominator==1&&f.numerator==1)printf("r%d - r%d",i,j);
        if(f.denominator==1&&f.numerator==-1)printf("r%d + r%d",i,j);
        else if(f.denominator==1&&f.numerator>1)printf("r%d - %d × r%d",i,f.numerator,j);
        else if(f.denominator==1&&f.numerator<-1)printf("r%d + %d × r%d",i,abs(f.numerator),j);
        else if(f.denominator!=1&&f.numerator>0)printf("r%d - %d/%d × r%d",i,f.numerator,f.denominator,j);
        else if(f.denominator!=1&&f.numerator<0)printf("r%d + %d/%d × r%d",i,abs(f.numerator),f.denominator,j);
        i--;j--;
        for(int x=0;x<n;x++)
        {
            mar[i][x]=minus(mar[i][x],time(f,mar[j][x]));
        }
        printMartrix(mar,"");
    }
}

void swapRowiRowj(Fraction mar[][N],int i,int j)
{
    if(i>=1&&i<=m&&j>=1&&j<=m)
    {
        printf("r%d <--> r%d",i,j);
        i--;j--;
        Fraction temp;
        for(int x=0;x<n;x++)
        {
            temp=mar[i][x];
            mar[i][x]=mar[j][x];
            mar[j][x]=temp;
        }
        printMartrix(mar,"");
    }
}

void sortRowByElemrc(Fraction mar[][N],int r,int c)
{
    if(r>=1&&r<=m&&c>=1&&c<=n)
    {
        r--;c--;
        for(int i=r;i<m-1;i++)
        {
            for(int j=i+1;j<m;j++)
            {
                if(mar[i][c].numerator==0&&mar[j][c].numerator!=0)
                {
                    swapRowiRowj(mar,i+1,j+1);
                }
            }
        }
    }
}

int haveNonZeroElemFromRowpInColumnq(Fraction mar[][N],int p,int q)
{
    if(p>=1&&p<=m&&q>=1&&q<=n)
    {
        p--;q--;
        int havenonzero=0;
        for(int x=p;x<m;x++)
        {
            if(mar[x][q].numerator!=0)
            {
                havenonzero=1;
            }
        }
        return havenonzero;
    }
}

void simplifyToSimplestRowForm(Fraction mar[][N])
{
    int k=1;
    int i=1;
    while(i>=1&&i<=m&&k>=1&&k<=n)
    {
        if(haveNonZeroElemFromRowpInColumnq(mar,i,k)==1)
        {
            for(int q=i;q<=m;q++)
            {
                simplifyRowi(mar,q);
            }
            sortRowByElemrc(mar,i,k);
            for(int q=i+1;q<=m;q++)
            {
                if(mar[q-1][k-1].numerator!=0)RowiminusRowj(mar,q,i);
            }
            i++;
            k++;
        }
        else if(haveNonZeroElemFromRowpInColumnq(mar,i,k)==0)k++;
    }

    k=1;
    i=1;
    while(i>=1&&i<=m&&k>=1&&k<=n)
    {
        if(haveNonZeroElemFromRowpInColumnq(mar,i,k)==1)
        {
                for(int q=1;q<i;q++)
                {
                    if(mar[q-1][k-1].numerator!=0)
                    {
                            RowiminusFractionkRowj(mar,q,i,divide(mar[q-1][k-1],mar[i-1][k-1]));
                    }
                }
            i++;
            k++;
        }
        else if(haveNonZeroElemFromRowpInColumnq(mar,i,k)==0)k++;
    }
}

int rank(Fraction mar[][N])
{
    int r=m;
    for(int i=m-1;i>=0;i--)
    {
        int fullrowzero=1;
        for(int j=0;j<n;j++)
        {
            if(mar[i][j].numerator!=0)fullrowzero=0;
        }
        if(fullrowzero==1)r--;
    }
    return r;
}

int main(void)
{
    Fraction mar[N][N];
    char c;
    do
    {
        initMartrix(mar);
        int t=0;
        do
        {
            if(!t)printf("\n请输入m×n矩阵的m n(1<=m,n<=9):");
            scanf("%d %d",&m,&n);
            t++;
        }while(!(m>=1&&m<=9&&n>=1&&n<=9)&&printf("请重输:"));
        inputMartrix(mar);
        printMartrix(mar,"\n原矩阵:");
        simplifyToSimplestRowForm(mar);
        printMartrix(mar,"行最简形:");
        puts("=======================================");
        printf("R=%d\n\n",rank(mar));
        printf("是否继续(Y/y)?");
        c=getche();
    }while(c=='Y'||c=='y');
    return 0;
}



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chenpeer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值