矩阵和矩阵转置

article/2025/8/27 5:23:45

一.矩阵乘

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();
}

运行结果

 


http://chatgpt.dhexx.cn/article/wFFx7qKV.shtml

相关文章

023 A转置矩阵=A的性质(三大性质)

A转置矩阵A的性质(三大性质)

矩阵转置相关公式_线性代数入门——矩阵的转置运算及对称矩阵的概念

系列简介:这个系列文章讲解线性代数的基础内容,注重学习方法的培养。线性代数课程的一个重要特点(也是难点)是概念众多,而且各概念间有着千丝万缕的联系,对于初学者不易理解的问题我们会不惜笔墨加以解释。在内容上,以国内的经典教材“同济版线性代数”为蓝本,并适当选取…

逆矩阵和转置矩阵的基本性质

1 逆矩阵 设A是一个n阶矩阵&#xff0c;若存在另一个n阶矩阵B&#xff0c;使得&#xff1a; ABBAE &#xff0c;则称方阵A可逆&#xff0c;并称方阵B是A的逆矩阵 [1]。 2 转置矩阵 将矩阵的行列互换得到的新矩阵称为转置矩阵&#xff0c;转置矩阵的行列式不变。 参考链接&am…

矩阵的基本性质【转置/求逆/伴随等】

速查目录 转置 A T A^T AT共轭矩阵共轭转置 A H A^H AH满秩分解的求法线性空间内积施密特正交化方法 转置 A T A^T AT ( A B ) T A T B T (A\pm B)^TA^T\pm B^T (AB)TATBT ( A B ) T B T A T (AB)^TB^TA^T (AB)TBTAT ( A T ) T A (A^T)^TA (AT)TA ( K A ) T K A T (KA)^…

4.9-4.10 矩阵乘法的性质 矩阵的幂运算 矩阵的转置及其性质

矩阵乘法的性质 矩阵的乘法不遵守交换律 &#xff01; 矩阵乘法遵守结合律、分配律 对于任意r行c列的矩阵A&#xff0c;存在c行x列的矩阵O&#xff0c;满足&#xff1a;A . Ocx Orx 对于任意r行c列的矩阵A&#xff0c;存在x行r列的矩阵O&#xff0c;满足&#xff1a;Oxr . A …

C语言中使用布尔变量注意事项

如果在C语言中直接定义bool变量时&#xff0c;编译结果会提示错误&#xff1a; 所以如果仍想使用bool作为类型名称&#xff0c;只需在使用它的源文件中给<stdbool.h>标准头文件添加#include指令即可。 接下来就一切照常编写代码啦&#xff01; 例如&#xff1a; 结果&…

面试题:布尔变量

点击上方“程序员大咖”&#xff0c;选择“置顶公众号” 关键时刻&#xff0c;第一时间送达&#xff01; 下面这篇文章是从StackOverflow来的。LZ面试的时候遇到了一道面试题&#xff1a;“如果有三个Bool型变量&#xff0c;请写出一程序得知其中有2个以上变量的值是true”&…

Java布尔类型变量命名与类型问题

Java布尔类型变量命名与类型问题 1. Java变量命名与类型概述2. 使用isXXX来命名变量问题3. 基本类型与包装类选择问题 1. Java变量命名与类型概述 平时业务开发过程中&#xff0c;实体创建的时候很多同学习惯使用isXXX开头命名一些属性&#xff0c;比如isDeleted&#xff0c;i…

Unity UI动画通过布尔变量来转换状态机的模板

通过布尔变量来转换状态机的模板 适用状态机的基本模式&#xff1a;使用方法&#xff1a;脚本代码 适用状态机的基本模式&#xff1a; 例如点一下弹出托盘&#xff0c;再点一下托盘收回的事件 状态机说明&#xff1a;其中ButtomPanel为收回状态&#xff0c;bool 变量 “press”…

Linux教程 - 在Shell脚本中声明和使用布尔变量示例

需要定义一个名为failed的bash变量&#xff0c;并将值设置为False。当从cron作业调用我们的脚本时&#xff0c;特定的任务可能会失败&#xff0c;然后我需要将failed转换为True。基于$failed&#xff0c;我需要发送一封电子邮件警告我的cron作业失败了。那么&#xff0c;如何在…

单片机 bdata是布尔变量的存储方式

bdata是布尔变量的存储方式 uchar是unsigned char类型 位变量flag被定义为bdata存储类型&#xff0c;编译时编译器将把该变量定位在51单片机片内数据存储区&#xff08;RAM&#xff09;中的位寻址区 uchar bdata rfLED[2] {0x00,0x00}; //用于存放遥控指示灯用。 long int time…

javascript 布尔_Javascript布尔变量类型

javascript 布尔 While making decisions we generally need some logic values. Logic values are generally true and false . In Javascript these values are called as Boolean type. Boolean type variables holds logic values true and false. This type is simpler ag…

Java基础入门笔记-布尔类型变量

代码如下所示&#xff1a; package my;public class HelloWorld {public static void main(String[] args){boolean bool_1true;boolean bool_2false;System.out.println("bool_1 is "bool_1);System.out.println("bool_2 is "bool_2);}} 运行结果如下所示…

【Python】布尔类型 ( 布尔类型变量 | 比较运算符 )

文章目录 一、布尔类型变量二、比较运算符三、代码示例 一、布尔类型变量 Python 中的 布尔类型 ( bool ) 用于 逻辑判断 , 布尔类型 是 数字类型 ( Number ) 的一种 , 其有两种 字面量 取值 : 真 : True , 其本质是数字 1 ;假 : False , 其本质是数字 0 ; 代码示例 : # 布尔…

跳板机相关

跳板机 跳板机什么是跳板机 堡垒机什么是堡垒机 JumpServer 跳板机 什么是跳板机 跳板机&#xff1a;开发人员需要先登录跳板机才可进入连接到开发机中&#xff08;机房&#xff09;。 缺点&#xff1a;缺少人员的控制及审计&#xff0c;无法追责 堡垒机 什么是堡垒机 堡…

xshell7 登录脚本 设置跳板机

xshell7 登录脚本 设置跳板机 在实际开发或生产环境&#xff0c;经常会出现跳板机&#xff0c;手动执行比较麻烦&#xff0c;故进行如下两步设置即可&#xff1a; 第一步 在会话管理器中将跳板机的 IP 填入到连接中&#xff0c;我实验的跳板机是 192.168.190.xxx&#xff0c;需…

Xshell 配置跳板机服务器登录目标服务器

文章目录 1. 配置跳板机服务器1.1. 配置连接1.2. 配置用户身份验证1.3. 配置 SSH 隧道 2. 配置目标服务器2.1. 配置连接2.2. 配置用户身份验证2.3. 配置代理 3. 连接成功 有时候一些服务器在内网中&#xff0c;外部网络无法直接访问&#xff0c;这时我们就需要使用跳板机服务器…

网络安全设备堡垒机跳板机VPN

文章目录 一、堡垒机&#xff08;Bastion Host&#xff09;1.1 定义1.2 作用 二、跳板机&#xff08;Jump Server&#xff09;2.1 定义2.2 作用 三、VPN&#xff08;Virtual Private Network&#xff09;3.1 定义3.2 作用 四、三者的区别 一、堡垒机&#xff08;Bastion Host&a…

ansible通过跳板机管理内网机器

一、场景&#xff1a; 1、服务器都是内网机器 2、跳板机是公网IP 3、想要使用Ansible管理内网主机 4、逻辑&#xff1a;ansible > 跳板机 > 内网机器 二、解决办法 2.1 测试机器&#xff1a; ansible&#xff1a; 192.168.199.201 jumper&#xff1a; 14.215.177.…

堡垒机 防止合法维护单位合法维护一台服务器的同时以这台服务器为跳板,跳板机与堡垒机最大的不同之处在哪?...

跳板机是什么?跳板机是开发人员登陆到网站分派给应用服务器的唯一途径。开发人员务必最先登陆跳板机&#xff0c;再根据跳板机登陆到应用服务器。再此&#xff0c;就不得不提堡垒机了&#xff0c;堡垒机的定义是一种安全管理工具&#xff0c;具有强大的防御作用和安全审计作用…