仲舟:这是我的第一篇博客,因为慕课编程作业越来越离谱,很多人发上百行代码问我错哪,由于每个人思路不同我基本要花近一个小时解决,所以特意写了篇博客,以后比较难点的问题我都会写博客,尽量把我的思路解释清楚,希望能对大家有所帮助,同时也是对我的学习过程一个记录。
///*题目:实现稀疏矩阵(采用三元组表示法)的基本运算
///*作者:仲舟
///*难度:★★★★★
///*完成时间: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;
}
仲舟原创,未经允许禁止转载!