栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

数据结构11:二维数组与矩阵乘法

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据结构11:二维数组与矩阵乘法

摘要: 二维数组在我们学习c语言的时候遇到过,现在我们来试试用数据结构对二维数组进行操作,并且顺便看看c语言是如何给二维数组分配空间的
一.代码块
1)创建

这里分为了静态和动态两个写法,由于静态操作比较简单,我们后续的函数用的动态。

#define ROWS 4
#define COLUMNS 5

 
typedef struct twoDArray
{
	int rows;
	int columns;
	int **elements;
}*towDArrayPtr;

//这种静态分配不用单独给数组malloc,由于这种比较简单,我们后续的都用的第一种 
typedef struct twoDStaticArray
{
	int rows;
	int columns;
	int elements[ROWS][COLUMNS];
}*twoDStaticArrayPtr;

2)初始化

在开始初始化函数之前,我们要知道一件事情:对于c语言来说,二维数组其实就是一个一维数组,只不过这个一维数组的每个元素又分别是一个一维数组。同理推广到三维数组甚至更高维。其次,c语言的的二维数组是以行序为主序的,即相当于二维数组的每一行单独是一个大的元素,第一行为第一个元素,第二行为第二个元素。

towDArrayPtr twoDArrayInit(int paraRows,int paraColumns)
{
	int i;
	//首先先给结构体 malloc 
	towDArrayPtr resultTwoDArray = (towDArrayPtr)malloc(sizeof(struct twoDArray));
	resultTwoDArray->rows = paraRows;
	resultTwoDArray->columns = paraColumns;
	
	//对于二维数组,先给最外层malloc
	resultTwoDArray->elements = (int**)malloc(paraRows * sizeof(int*));
	
	//然后,在对我们说的每一行的大元素malloc,空间就是每一行元素的个数,即列数
	for(i = 0;i < resultTwoDArray->rows;i ++)
	{
		
		resultTwoDArray->elements[i] = (int*)malloc(paraColumns * sizeof(int));
	}
	
	return  resultTwoDArray;
	 
}

3)打印

void outputTwoDArray(towDArrayPtr 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("n");
	}
	
	printf("rn");
}

4)随机赋值

void randomizeTwoDArray(towDArrayPtr paraPtr, int paraLowerBound, int paraUpperBound)
{
	int i, j;	
	//这里就是一个随机函数,在stdlib头文件里面,给定上下界然后给每个元素赋随机值 
	for (i = 0; i < paraPtr->rows; i ++)
	{
		for (j = 0; j < paraPtr->columns; j ++) 
		{
			paraPtr->elements[i][j] = rand() % (paraUpperBound - paraLowerBound) + paraLowerBound;
		}
	}
}

5)矩阵的乘法

我们要先知道矩阵相乘是怎么算的,然后解读一下这个三重循环

首先,前两重循环就是遍历我们要的矩阵,给每一个矩阵赋值。
第三重循环就是执行我们每一个位置的元素是如何得到的,就是
第一个矩阵的第i行每个位置的元素乘以第二个矩阵的第j列每个位置
的元素,再把他们加起来。读者需要自行画个矩阵跟踪一下就会明朗很多

towDArrayPtr matrixMultiply(towDArrayPtr paraPtr1,towDArrayPtr paraPtr2)
{
	int i,j,k,sum;
	if(paraPtr1->columns != paraPtr2->rows)
	{
		printf("这个两个矩阵不能相乘哦0.0n");
		return ; 
	}
	towDArrayPtr resultPtr;
	resultPtr = twoDArrayInit(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; 
		}
		
	return resultPtr; 
}

6)静态版的初始化并且打印其地址

这里简单的给静态数组赋值输出一下,重点是地址的打印让我们直到c语言是怎么看待二维数组的

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; n", i, j, &(resultPtr->elements[i][j]));
		}
	}
	
	return resultPtr;
}

7)测试函数

void twoDArrayTest()
{
	towDArrayPtr tempPtr1, tempPtr2, tempPtr3;
	tempPtr1 = twoDArrayInit(3, 2);
	randomizeTwoDArray(tempPtr1, 1, 5);
	printf("The first matrix:rn");
	outputTwoDArray(tempPtr1);

	tempPtr2 = twoDArrayInit(2, 4);
	randomizeTwoDArray(tempPtr2, 4, 9);
	printf("The second matrix:rn");
	outputTwoDArray(tempPtr2);

	tempPtr3 = matrixMultiply(tempPtr1, tempPtr2);
	printf("The result:rn");
	outputTwoDArray(tempPtr3);
}

三.全部代码

#include 
#include 
#include 

#define ROWS 4
#define COLUMNS 5

 
typedef struct twoDArray
{
	int rows;
	int columns;
	int **elements;
}*towDArrayPtr;

//这种静态分配不用单独给数组malloc,由于这种比较简单,我们后续的都用的第一种 
typedef struct twoDStaticArray
{
	int rows;
	int columns;
	int elements[ROWS][COLUMNS];
}*twoDStaticArrayPtr;


towDArrayPtr twoDArrayInit(int paraRows,int paraColumns)
{
	int i;
	//首先先给结构体 malloc 
	towDArrayPtr resultTwoDArray = (towDArrayPtr)malloc(sizeof(struct twoDArray));
	resultTwoDArray->rows = paraRows;
	resultTwoDArray->columns = paraColumns;
	
	//对于二维数组,先给最外层malloc
	resultTwoDArray->elements = (int**)malloc(sizeof(int*));
	
	//然后,在对我们说的每一行的大元素malloc,空间就是每一行元素的个数,即列数
	for(i = 0;i < resultTwoDArray->rows;i ++)
	{
		
		resultTwoDArray->elements[i] = (int*)malloc(sizeof(int));
	}
	
	return  resultTwoDArray;
	 
}

void randomizeTwoDArray(towDArrayPtr paraPtr, int paraLowerBound, int paraUpperBound)
{
	int i, j;	
	//这里就是一个随机函数,在stdlib头文件里面,给定上下界然后给每个元素赋随机值 
	for (i = 0; i < paraPtr->rows; i ++)
	{
		for (j = 0; j < paraPtr->columns; j ++) 
		{
			paraPtr->elements[i][j] = rand() % (paraUpperBound - paraLowerBound) + paraLowerBound;
		}
	}
}

void outputTwoDArray(towDArrayPtr 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("n");
	}
	
	printf("rn");
}

towDArrayPtr matrixMultiply(towDArrayPtr paraPtr1,towDArrayPtr paraPtr2)
{
	int i,j,k,sum;
	if(paraPtr1->columns != paraPtr2->rows)
	{
		printf("这个两个矩阵不能相乘哦0.0n");
		return ; 
	}
	towDArrayPtr resultPtr;
	resultPtr = twoDArrayInit(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; 
		}
		
	return resultPtr; 
}

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; n", i, j, &(resultPtr->elements[i][j]));
		}
	}
	
	return resultPtr;
}

void twoDArrayTest()
{
	towDArrayPtr tempPtr1, tempPtr2, tempPtr3;
	tempPtr1 = twoDArrayInit(3, 2);
	randomizeTwoDArray(tempPtr1, 1, 5);
	printf("The first matrix:rn");
	outputTwoDArray(tempPtr1);

	tempPtr2 = twoDArrayInit(2, 4);
	randomizeTwoDArray(tempPtr2, 4, 9);
	printf("The second matrix:rn");
	outputTwoDArray(tempPtr2);

	tempPtr3 = matrixMultiply(tempPtr1, tempPtr2);
	printf("The result:rn");
	outputTwoDArray(tempPtr3);
}

int main()
{
	twoDArrayTest();
	twoDStaticArrayPtr tempPtr = initTwoDStaticArray();
}

四.运行结果

矩阵运行结果

The first matrix:
2 4
3 1
2 1

The second matrix:
7 7 6 8
4 4 5 6

The result:
30 30 32 40
25 25 23 30
18 18 17 22

打印地址结果

(0, 0): 11408888;
(0, 1): 11408892;
(0, 2): 11408896;
(0, 3): 11408900;
(0, 4): 11408904;
(1, 0): 11408908;
(1, 1): 11408912;
(1, 2): 11408916;
(1, 3): 11408920;
(1, 4): 11408924;
(2, 0): 11408928;
(2, 1): 11408932;
(2, 2): 11408936;
(2, 3): 11408940;
(2, 4): 11408944;
(3, 0): 11408948;
(3, 1): 11408952;
(3, 2): 11408956;
(3, 3): 11408960;
(3, 4): 11408964;

可以很明显的看到,c语言是以行序为主序的。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/913204.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号