一.矩阵乘
1.老师的代码
1.结构体
typedef struct TwoDArray{int rows;int columns;int **elements;
}*TwoDArrayPtr;typedef struct TwoDStaticArray{int rows;int columns;int elements[ROWS][COLUMNS];
}*TwoDStaticArrayPtr;
2.初始化
TwoDArrayPtr initTwoDArray(int paraRows,int paraColumns){int i;TwoDArrayPtr resultPtr=(TwoDArrayPtr)malloc(sizeof(struct TwoDArray));resultPtr->columns=paraColumns;resultPtr->rows=paraRows;resultPtr->elements=(int**)malloc(sizeof(int)*paraRows);for(i=0;i<paraRows;i++){resultPtr->elements[i]=(int*)malloc(sizeof(int)*paraColumns);}return resultPtr;
}
3.随机数
void randomizeTwoDArray(TwoDArrayPtr paraPtr,int paraLowerBound,int paraUpperBound){int i,j; for(i=0;i<paraPtr->rows;i++){for(j=0;j<paraPtr->columns;j++){paraPtr->elements[i][j]=rand()%(paraUpperBound-paraLowerBound)+paraLowerBound;}}
}
4.打印函数
void printTwoDArray(TwoDArrayPtr paraPtr){int i,j;for(i=0;i<paraPtr->rows;++i){for(j=0;j<paraPtr->columns;j++){printf("%d, ",paraPtr->elements[i][j]);}printf("\r\n");}}
5.矩阵乘
TwoDArrayPtr matrixMultiply(TwoDArrayPtr paraPtr1,TwoDArrayPtr paraPtr2){int i,j,k,sum;if(paraPtr1->columns!=paraPtr2->rows){printf("Matrices cannot be multiplied\r\n");return NULL;}TwoDArrayPtr resultPtr=initTwoDArray(paraPtr1->rows,paraPtr2->columns);for(i=0;i<paraPtr1->rows;i++){for(j=0;j<paraPtr2->columns;j++){sum=0;for(k=0;k<paraPtr1->columns;k++){sum+=paraPtr1->elements[i][k]*paraPtr2->elements[k][j];}resultPtr->elements[i][j]=sum;printf("sum=%d, ",sum);}}return resultPtr;
}
图解:
最内层循环对应逐个相乘再相加,中间层对应第一个矩阵指定行和第二个矩阵逐行相乘 ,最外层对应第一个矩阵逐行运算。
6.测试函数
void twoDArrayTest(){TwoDArrayPtr tempPtr1,tempPtr2,tempPtr3;tempPtr1=initTwoDArray(3,2);randomizeTwoDArray(tempPtr1,1,5);printf("The frist matrix:\r\n");printTwoDArray(tempPtr1);tempPtr2=initTwoDArray(2,4);randomizeTwoDArray(tempPtr2,4,9);printf("The second matrix:\r\n");printTwoDArray(tempPtr2);tempPtr3=matrixMultiply(tempPtr1,tempPtr2);//printf("yes\r\n");printf("The result matrix:\r\n");printTwoDArray(tempPtr3);
}
7.静态矩阵
TwoDStaticArrayPtr initTwoDStaticArray(){int i, j;TwoDStaticArrayPtr resultPtr = (TwoDStaticArrayPtr)malloc(sizeof(struct TwoDStaticArray));resultPtr->rows=ROWS;resultPtr->columns=COLUMNS;for (i=0;i<ROWS;i++){for (j=0;j<COLUMNS;j ++){resultPtr->elements[i][j]=i*10+j;printf("(%d, %d): %d; ",i,j,&(resultPtr->elements[i][j]));}}return resultPtr;
}
运行结果
2.自己的代码
1.结构体
typedef struct two{int rows;int columns;int* data;
}*twoptr;
此处只定义了一个结构体,data指向一片malloc得到的区域
2.初始化
twoptr init(int h,int s){twoptr t=(twoptr)malloc(sizeof(struct two));t->rows=h;t->columns=s;t->data=(int*)malloc(sizeof(int)*h*s);for(int i=0;i<h;++i){for(int j=0;j<s;++j)t->data[i*h+j]=2*i+3*j+4*s*h;}return t;
}
3.打印
void print(twoptr p){int i,j;for(i=0;i<p->rows;i++){for(j=0;j<p->columns;++j)printf("%d ",p->data[i*(p->rows)+j]);printf("\r\n");}}
4.test函数
void test(){twoptr matrixA,matrixB,result;matrixA=init(4,6);printf("初始化矩阵A:\r\n");print(matrixA);matrixB=init(6,5);printf("初始化矩阵B:\r\n");print(matrixB);//printf("YES\r\n");result=multiply(matrixA,matrixB);printf("矩阵乘结果:\r\n");print(result);
}
运行结果
二.转置矩阵
1.老师的代码
1.结构体
typedef struct Triple{int i;int j;elem e;
} Triple,*TriplePtr;typedef struct CompressedMatrix{int rows,columns,numElements;Triple* elements;
} CompressedMatrix,*CompressedMatrixPtr;
2.初始化
CompressedMatrixPtr initCompressedMatrix(int paraRows,int paraColumns,int paraElements,int** paraData){int i;CompressedMatrixPtr resultPtr=(CompressedMatrixPtr)malloc(sizeof(struct CompressedMatrix));resultPtr->rows=paraRows;resultPtr->columns=paraColumns;resultPtr->numElements=paraElements;resultPtr->elements=(TriplePtr)malloc(paraElements*sizeof(struct Triple));for(i=0;i<paraElements;i++){resultPtr->elements[i].i=paraData[i][0];resultPtr->elements[i].j=paraData[i][1];resultPtr->elements[i].e=paraData[i][2];}return resultPtr;
}
3.打印
void printCompressedMatrix(CompressedMatrixPtr paraPtr){int i;for(i=0;i<paraPtr->numElements;i++){printf("(%d, %d): %d\r\n",paraPtr->elements[i].i,paraPtr->elements[i].j,paraPtr->elements[i].e);}
}
4.转置
CompressedMatrixPtr transposeCompressedMatrix(CompressedMatrixPtr paraPtr){int i,tempColumn,tempPosition;int *tempColumnCounts=(int*)malloc(paraPtr->columns*sizeof(int));int *tempOffsets=(int*)malloc(paraPtr->columns*sizeof(int));for(i=0;i<paraPtr->columns;i++){tempColumnCounts[i]=0;}CompressedMatrixPtr resultPtr=(CompressedMatrixPtr)malloc(sizeof(struct CompressedMatrix));resultPtr->rows=paraPtr->columns;resultPtr->columns=paraPtr->rows;resultPtr->numElements=paraPtr->numElements;resultPtr->elements=(TriplePtr)malloc(paraPtr->numElements*sizeof(struct Triple));for(i=0;i<paraPtr->numElements;i++) {tempColumnCounts[paraPtr->elements[i].j]++;}tempOffsets[0]=0;for(i=1;i<paraPtr->columns;i++){tempOffsets[i]=tempOffsets[i-1]+tempColumnCounts[i-1];printf("tempOffsets[%d] = %d \r\n",i,tempOffsets[i]);}for(i=0;i<paraPtr->numElements;i++){tempColumn=paraPtr->elements[i].j;tempPosition=tempOffsets[tempColumn];resultPtr->elements[tempPosition].i=paraPtr->elements[i].j;resultPtr->elements[tempPosition].j=paraPtr->elements[i].i;resultPtr->elements[tempPosition].e=paraPtr->elements[i].e;tempOffsets[tempColumn]++;}return resultPtr;
}
要保证转置后的数组是有序的,则应扫描后预先规划好行的起始位置
第一步:扫描整个矩阵,得到各列数的统计(橙色),在根据其推出转置后的矩阵各行将要放的逻辑行数(黄色)
第二步:根据第二个方框(黄色)得到转置矩阵 ,每加一行方框内对应位置加一
最终结果如图:
5.test
void compressedMatrixTest(){CompressedMatrixPtr tempPtr1,tempPtr2;int i,j,tempElements;tempElements =4;int** tempMatrix1=(int**)malloc(tempElements*sizeof(int*));for(i=0;i<tempElements;i++){tempMatrix1[i]=(int*)malloc(3*sizeof(int));}int tempMatrix2[4][3]={{0,0,2},{0,2,3},{2,0,5},{2,1,6}};for(i=0;i<tempElements;i++){for(j=0;j<3;j++) {tempMatrix1[i][j]=tempMatrix2[i][j];}}tempPtr1=initCompressedMatrix(2,3,4,tempMatrix1);printf("After initialization.\r\n");printCompressedMatrix(tempPtr1);tempPtr2=transposeCompressedMatrix(tempPtr1);printf("After transpose.\r\n");printCompressedMatrix(tempPtr2);
}
运行结果
2.我的代码
#include <stdio.h>
#include <malloc.h>typedef struct three{int i;int j;int data;
}*threeptr;typedef struct compresse{int rows;int columns;int datanum;struct three* dataTH;
}*compresseptr;compresseptr init(int rows,int columns,int elements,int** data){compresseptr result=(compresseptr)malloc(sizeof(struct compresse));result->rows=rows;result->columns=columns;result->datanum=elements;result->dataTH=(threeptr)malloc(elements*sizeof(struct three));for(int i=0;i<elements;i++){result->dataTH[i].i=data[i][0];result->dataTH[i].j=data[i][1];result->dataTH[i].data=data[i][2];}return result;
}void print(compresseptr p){for(int i=0;i<p->datanum;i++)printf("position (%d, %d) data = %d\r\n",p->dataTH[i].i,p->dataTH[i].j,p->dataTH[i].data);
}compresseptr trans(compresseptr p){int column2,position;int *counts=(int*)malloc(p->columns*sizeof(int));for(int i=0;i<p->columns;i++)counts[i]=0;compresseptr result=(compresseptr)malloc(sizeof(struct compresse));result->rows=p->columns;result->columns=p->rows;result->datanum=p->datanum;result->dataTH=(threeptr)malloc(p->datanum*sizeof(struct three));for(int i=0;i<p->datanum;i++) counts[p->dataTH[i].j]++; int *offsets=(int*)malloc(p->columns*sizeof(int)); offsets[0]=0;for(int i=1;i<p->columns;i++){offsets[i]=offsets[i-1]+counts[i-1];printf("offsets[%d] = %d \r\n",i,offsets[i]);}for(int i=0;i<p->datanum;i++){column2=p->dataTH[i].j;position=offsets[column2];result->dataTH[position].i=p->dataTH[i].j;result->dataTH[position].j=p->dataTH[i].i;result->dataTH[position].data=p->dataTH[i].data;offsets[column2]++;}return result;
}void test(){compresseptr p,q;int element2=4;int** matrix1=(int**)malloc(element2*sizeof(int*));for(int i=0;i<element2;i++)matrix1[i]=(int*)malloc(3*sizeof(int));int matrix2[4][3]={{0,1,7},{0,2,3},{2,2,10},{2,1,8}};for(int i=0;i<element2;i++)for(int j=0;j<3;j++)matrix1[i][j]=matrix2[i][j];p=init(2,3,4,matrix1);printf("初始化:\r\n");print(p);q=trans(p);printf("转置:\r\n");print(q);
}void main(){test();
}
运行结果