仲舟のMOOC第六周编程作业

仲舟:这是我的第一篇博客,因为慕课编程作业越来越离谱,很多人发上百行代码问我错哪,由于每个人思路不同我基本要花近一个小时解决,所以特意写了篇博客,以后比较难点的问题我都会写博客,尽量把我的思路解释清楚,希望能对大家有所帮助,同时也是对我的学习过程一个记录。

///*题目:实现稀疏矩阵(采用三元组表示法)的基本运算 
///*作者:仲舟                                       
///*难度:★★★★★
///*完成时间:2021.04.20
#include <stdio.h>
#define maxsize 100

typedef enum {false,true} bool;
typedef struct {
    int  data[100][100];  /*二维数组*/
    int  rows,cols;             /*行数和列数*/
} Matrix; //稀疏矩阵

typedef struct {
    int  row,col;  /*行号、列号*/
    int  item; /*非零元素值*/
} TupleNode; /*三元组的类型 */

typedef struct {
    TupleNode data[maxsize];
    int  rows,cols;  /*行数、列数*/
    int  nums; /*非零元个数*/
} TSMatrix; /*三元组顺序表的类型 */

void  Compressmatrix(Matrix A, TSMatrix *B);//产生稀疏矩阵A的三元组表示t
bool  Value(TSMatrix *t,int x,int i,int j);//将x赋值给三元组t中稀疏矩阵A的A[i][j],并返回true,若i,j非法,返回false
bool  Assign(TSMatrix t,int *x,int i,int j); //取三元组t中稀疏矩阵A的A[i][j]的值赋给指针变量x所指变量,并返回true,若i,j非法,返回false
void  Print(TSMatrix B);  //输出三元组
void  Transpmatrix (TSMatrix B, TSMatrix *C);//求三元组表示B的转置矩阵(仍使用三元组表示)

/*添加函数*/
int OneDimensionValue(TSMatrix t,int i,int j);//计算三元组转化为一维组后所求矩阵距第一个下标之差
void Insert(TSMatrix *t,int i,int j,int x);//插入一个元素(0就不插)
void Delete(TSMatrix *t,int i,int j);//删除一个元素(值为0)
void swap(int *x,int *y);//交换

main() {
    int i,j,k,x,rows,cols,N;
    bool flag;
    Matrix A;
    TSMatrix B,C;
    scanf("%d%d",&rows,&cols);
    A.rows=rows;
    A.cols=cols;
    for ( i=0; i<rows; i++)
        for (j=0; j<cols; j++)
            scanf("%d",&A.data[i][j]);
    Compressmatrix(A,&B);
    Print(B);

    Transpmatrix (B, &C);
    printf("the transpose of this matrix\n");
    Print(C);
    scanf("%d",&N);
    for (k=0; k<N; k++) {
        scanf("%d%d",&i,&j);
        flag=Assign(B,&x,i,j);
        if (flag==true) {
            printf("A[%d,%d]=%d\n",i,j,x);
        } else {
            printf("A[%d,%d] is wrong\n",i,j);
        }
    }
    scanf("%d",&N);
    for (k=0; k<N; k++) {
        scanf("%d%d%d",&i,&j,&x);
        flag=Value(&B,x,i,j);
        if (flag==true) {
            printf("success\n");
        } else {
            printf("A[%d,%d] is wrong\n",i,j);
        }
        Print(B);
    }


}
void Print(TSMatrix B) {
    int i;
    printf("%5d%5d%5d",B.data[0].row,B.data[0].col,B.data[0].item);
    for ( i=1; i<B.nums;  i++) {
        printf("\n%5d%5d%5d",B.data[i].row,B.data[i].col,B.data[i].item);
    }
    printf("\n");

}
//你的代码写在这里 ,注意提交完整程序进行测试

void  Compressmatrix(Matrix A, TSMatrix *B) { //产生稀疏矩阵A的三元组表示t
    /*B的初始化*/
    B->nums=0;
    B->cols=A.cols;
    B->rows=A.rows;
    /*找非0矩阵转移*/
    for (int i=0; i<A.rows; i++)
        for (int j=0; j<A.cols; j++)
            if(A.data[i][j]!=0) {
                B->data[B->nums].item=A.data[i][j];
                B->data[B->nums].row=i;
                B->data[B->nums].col=j;
                B->nums++;
            }
}

bool  Value(TSMatrix *t,int x,int i,int j)//将x赋值给三元组t中稀疏矩阵A的A[i][j],并返回true,若i,j非法,返回false
{
    if(i<0||i>=t->cols||j<=0||j>=t->rows)//如果非法
        return false;
    else { //如果合法
        /*开始查找*/
        int flag=0;//是否找到
        for(int k=0; !flag&&k<=t->nums-1; k++)
            if(t->data[k].row==i&&t->data[k].col==j) {//如果找到
                if(x==0)//如果x==0,要删除
                    Delate(t,i,j);//删除(i,j)的位置
                else { //如果x!=0,则修改
                    flag=1;
                    t->data[k].item=x;
                }
            }
        if(flag==0&&x!=0)//如果没找到(如果x=0就不用插入)
            Insert(t,i,j,x);//新建(i,j)的一个位置并令其值为x
        return true;
    }
}

void Insert(TSMatrix *t,int i,int j,int x) {
    /*查找插入位置*/
    int perrow=-1,percol=-1,row,col,pos,flag=0,now,past,find;//前者行列,当前行列,插入位置,是否找到区间,现在、过去、要找的一维值
    for(int k=0; !flag&& k<=t->nums-1; k++) {
        row=t->data[k].row;
        col=t->data[k].col;
        find=OneDimensionValue(*t,i,j);
        now=OneDimensionValue(*t,row,col);
        past=OneDimensionValue(*t,perrow,percol);
        if(find>past&&find<now ){ //如果所插入一位值大于前者小于后者,两者之间
            pos=k;
            flag=1;
        }
    }
    if(flag==0)//如果没找到区间,就加在最后一行
        pos=t->nums+1;
    /*元素后移*/
    for(int k=++t->nums; k>=pos+1; k--) {
        t->data[k].col=t->data[k-1].col;
        t->data[k].row=t->data[k-1].row;
        t->data[k].item=t->data[k-1].item;
    }
    /*插入元素*/
    t->data[pos].row=i;
    t->data[pos].col=j;
    t->data[pos].item=x;
}

void Delate(TSMatrix *t,int i,int j) {
    /*查找位置*/
    for(int k=0; k<=t->nums-1; k++) {
        if(t->data[k].row==i&&t->data[k].col==j) {//如果找到开始前移
            for(int m=k; m<=t->nums-2; m++) {
                t->data[m].col=t->data[m+1].col;
                t->data[m].row=t->data[m+1].row;
                t->data[m].item=t->data[m+1].item;
            }
            break;
        }
    }
    t->nums--;
}

int OneDimensionValue(TSMatrix t,int i,int j) {
    return i*t.rows+j;
}

bool  Assign(TSMatrix t,int *x,int i,int j) {
    if(i<0||i>=t.cols||j<=0||j>=t.rows)//如果非法
        return false;
    else { //如果合法
        int flag=0;//是否找到
        for(int k=0; !flag&&k<=t.nums-1; k++)
            if(t.data[k].row==i&&t.data[k].col==j) {//如果找到
                *x=t.data[k].item;
                flag=1;
            }
        if(flag==0)//如果没找到那就说明等于0
            *x=0;
        return true;
    }
}

void  Transpmatrix (TSMatrix B, TSMatrix *C) { //求三元组表示B的转置矩阵(仍使用三元组表示)
    /*C数组初始化*/
    C->cols=B.rows;
    C->rows=B.cols;
    C->nums=B.nums;
    /*B矩阵转置*/
    for(int i=0; i<=B.nums-1; i++)
        swap(&B.data[i].col,&B.data[i].row);
    /*插入排序*/
    int min,pos,pmin=-1,now;//一维最小值,最小值下标,已输入最小值,当前一维下标值
    for(int j=0; j<=B.nums-1; j++){
        min=1<<20;//min初始化最大值
        for(int i=0; i<=B.nums-1; i++) {
            now=OneDimensionValue(B,B.data[i].row,B.data[i].col);
            if(now<min&&now>pmin) {//找除去已经找的值的最小值
                min=now;
                pos=i;
            }
        }
        /*矩阵转移*/
        C->data[j].item=B.data[pos].item;
        C->data[j].row=B.data[pos].row;
        C->data[j].col=B.data[pos].col;
        pmin=min;//记录该最小一维值
    }
}

void swap(int *x,int *y) {
    int temp=0;
    temp=*x;
    *x=*y;
    *y=temp;
}
///*题目:实现稀疏矩阵(采用三元组表示法)的加法运算 
///*作者:仲舟                                       
///*难度:★★★
///*完成时间:2021.04.20
#include <stdio.h>
#include<stdlib.h>
#define maxsize 100

typedef enum {false,true} bool;
typedef struct {
    int  data[100][100];  /*二维数组*/
    int  rows,cols;             /*行数和列数*/
} Matrix;

typedef struct {
    int  row,col;  /*行号、列号*/
    int  item; /*非零元素值*/
} TupleNode; /*三元组的类型 */

typedef struct {
    TupleNode data[maxsize];
    int  rows,cols;  /*行数、列数*/
    int  nums; /*非零元个数*/
} TSMatrix; /*三元组顺序表的类型 */

TSMatrix * Compressmatrix(Matrix T);//产生稀疏矩阵A的三元组表示t
void  Print(TSMatrix B);  //输出三元组
bool  Addmatrix(TSMatrix A,TSMatrix B, TSMatrix *C);// 求C=A+B; 若A,B矩阵行数或者列数不等,返回false ,否则返回true

/*添加函数*/
int OneDimensionValue(TSMatrix t,int i,int j);//计算三元组转化为一维组后所求矩阵距第一个下标之差

main() {
    int i,j,k,x,rows,cols,N;
    bool flag;
    Matrix T;
    TSMatrix *A,*B,C;
    scanf("%d%d",&rows,&cols);
    T.rows=rows;
    T.cols=cols;
    for ( i=0; i<rows; i++)
        for (j=0; j<cols; j++)
            scanf("%d",&T.data[i][j]);
    A=Compressmatrix(T);
    scanf("%d%d",&rows,&cols);
    T.rows=rows;
    T.cols=cols;
    for ( i=0; i<rows; i++)
        for (j=0; j<cols; j++)
            scanf("%d",&T.data[i][j]);
    B=Compressmatrix(T);
    flag=Addmatrix(*A,*B, &C);
    if (flag==false) {
        printf("cannot Add\n");
    } else {
        printf("the result:\n");
        Print(C);
    }
}
void Print(TSMatrix B) {
    int i;
    printf("%5d%5d%5d",B.data[0].row,B.data[0].col,B.data[0].item);
    for ( i=1; i<B.nums;  i++) {
        printf("\n%5d%5d%5d",B.data[i].row,B.data[i].col,B.data[i].item);
    }
    printf("\n");

}

TSMatrix * Compressmatrix(Matrix T) { //产生稀疏矩阵A的三元组表示t
    /*B矩阵初始化*/
    TSMatrix *B;
    B=(TSMatrix*)malloc(sizeof(TSMatrix));
    B->nums=0;
    B->cols=T.cols;
    B->rows=T.rows;
    /*找非0矩阵转移*/
    for (int i=0; i<T.rows; i++)
        for (int j=0; j<T.cols; j++)
            if(T.data[i][j]!=0) {//是非0就读入
                B->data[B->nums].item=T.data[i][j];
                B->data[B->nums].row=i;
                B->data[B->nums].col=j;
                B->nums++;
            }
    return B;
}

bool  Addmatrix(TSMatrix A,TSMatrix B, TSMatrix *C) {
    if(A.cols!=B.cols||A.rows!=B.rows)//如果A和B两矩阵非法
        return false;
    else { //如果合法
        int anow,bnow,i,j;//A矩阵的当前一维值,B矩阵的当前一维值
        C->cols=A.cols;
        C->rows=A.rows;
        /*双指针对比找最小的一方给C,当有矩阵用完就退出*/
        for(i=0,j=0; i<=A.nums-1&&j<=B.nums-1;) {
            anow=OneDimensionValue(A,A.data[i].row,A.data[i].col);
            bnow=OneDimensionValue(B,B.data[j].row,B.data[j].col);
            if(anow>bnow) {
                C->data[C->nums].row=B.data[j].row;
                C->data[C->nums].col=B.data[j].col;
                C->data[C->nums].item=B.data[j].item;
                C->nums++;
                j++;//下一个B.data
            }
            if(anow==bnow) {
                if(A.data[i].item+B.data[j].item!=0) {//相加可能会产生值为0的情况,应舍去
                    C->data[C->nums].row=B.data[j].row;
                    C->data[C->nums].col=B.data[j].col;
                    C->data[C->nums].item=A.data[i].item+B.data[j].item;
                    C->nums++;
                }
                i++;
                j++;//因为两矩阵同位置相加,所以两边该位置元素同时消除
            }
            if(anow<bnow) {
                C->data[C->nums].row=A.data[i].row;
                C->data[C->nums].col=A.data[i].col;
                C->data[C->nums].item=A.data[i].item;
                C->nums++;
                i++;//下一个A.data
            }
        }
        /*把还存在元素的矩阵顺序放入C(下面循环正常情况下只会执行一个)*/
        for(; i<=A.nums-1; i++) {
            C->data[C->nums].row=A.data[i].row;
            C->data[C->nums].col=A.data[i].col;
            C->data[C->nums].item=A.data[i].item;
            C->nums++;
        }
        for(; j<=B.nums-1; j++) {
            C->data[C->nums].row=B.data[j].row;
            C->data[C->nums].col=B.data[j].col;
            C->data[C->nums].item=B.data[j].item;
            C->nums++;
        }
        return true;
    }
}

int OneDimensionValue(TSMatrix t,int i,int j) {
    return i*t.rows+j;
}

仲舟原创,未经允许禁止转载!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值