见微知著——依旧是矩阵乘法算法!

  博主上大二了,接触linux自我认为还是一个有小小追求的人,觉得一直漂浮在上层没有根基,于是还是想看看linux内核,便重新看是看pointers on c扎实c语言基础。不再急功近利,不再认为看完书就学到了知识,实践出真知,自己动手才是王道。不多说,就用一个以前我写过的例子嘲讽以前的我吧!

  还是一样的,pointers on c的chapter8的第五个编程小题。

  函数原型

void matrix_multiply ( int *m1 , int *m2 ,int *r , int x , int y , int z );
//其中m1是第一个数组,m2是第二个数组,m3是输出数组x,y是m1数组的行列号,y,z是m2的行列号

  先看第一遍的

void matrix_multiply ( int *m1 , int *m2 ,
		int *r , int x , int y , int z )
{
	int i = 0;
	int j = 0;
	int k = 0;

	for ( i = 0 ; i < x ; i++ )
	{
		for ( k = 0 ; k < z ; k++ )
		{
			for ( j = 0 ; j < y ; j++ )
			{
				*(*(&r+i)+k) += (*(*(&m1+i)+j)) * (*(*(&m2+j)+k));
			}
		}
	}
}

  算法很简单,我的思路再反复确定之后认为没有错误,但是编译执行之后一直会出现,segmentation fault (core dumped)也就是传说中的数组越界。想了一下才明白问题的所在——r,m1,m2不是数组名!

  假设有数组名a,那么&a会是当前的地址,并且假设a是一维数组,那么&a就是从列指针转化为行指针,具体的实例可以假设int a[10];只需要printf一下a+1的地址和&a+1的地址结果就显而易见!但是在这个题目中,不会将m1,m2,r当做数组名的,即使你将函数原型改为int m1[]这样的也可以,这里会当做是变量来处理。由于这里函数原型中的形参是*m1,*m2,*r这样的列指针,我想当然的认为这里可以转化行指针来处理,但实际上并不可以,因为这里是在堆栈中的变量。

  那么问题究竟出在哪里那?

  参考一个例子

  firstfile.c:

  int a[10];

  int *b=a;

  ...

  secondfile.c:

  extern int *a;

  extern int b[];

  ...

  那么a[3]和b[3]的值会是什么那?这里由于第二个文件中会把a当做指针变量处理,取出指针变量位置中存储的值,再加上3*sizeof(int)得到一个值,再对得到的值解引用,取出那个位置中的值,而实际上a是数组名,那么最后的结果就是取出(a[0]+12)这个地址的值。(这个访问一般情况下是非法的)

  而这里会将b当做是数组名,直接将b的地址加上12再解引用取值,这里也会是非法访问的。

  其实仔细想想,就是一个根本区别——变量会创建空间,而数组名不会!

  经过以上的思想挣扎之后我发现这里只能用列指针来进行操作,所以第二遍我就是对的了,嘿嘿!

  

void matrix_multiply ( int *m1 , int *m2 ,
		int *r , int x , int y , int z )
{
	int	i = 0;
	int j = 0;
	int k = 0;

	for ( i = 0 ; i < x ; i++ )
	{
		for ( k = 0 ; k < z ; k++ )
		{
			for ( j = 0 ; j < y ; j++ )
			{
				*(r+i*z+k) += *(m1+i*y+j) * *(m2+j*z+k);
			}
		}
	}
}

  虽然只是改了一行,但是我还是感觉蛮好的!

时间: 2024-08-10 18:59:30

见微知著——依旧是矩阵乘法算法!的相关文章

C语言 &#183; 矩阵乘法 &#183; 算法训练

问题描述 给定一个N阶矩阵A,输出A的M次幂(M是非负整数) 例如: A = 1 2 3 4 A的2次幂 7 10 15 22 输入格式 第一行是一个正整数N.M(1<=N<=30, 0<=M<=5),表示矩阵A的阶数和要求的幂数 接下来N行,每行N个绝对值不超过10的非负整数,描述矩阵A的值 输出格式 输出共N行,每行N个整数,表示A的M次幂所对应的矩阵.相邻的数之间用一个空格隔开 样例输入 2 21 23 4 样例输出 7 1015 22 代码如下: #include<s

算法重拾之路——strassen矩阵乘法

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 第一章:分治与递归 STRASSEN矩阵乘法 算法描述: 矩阵乘法是线性代数中最常见的问题之一,它在数值计算中有广泛的应用.设A 和 B 是两个n × n矩阵,它们的乘积AB同样是一个n×n矩阵.A和B的乘积矩阵C 中的元素cij定义为: 按照这个定义来看,计算

【甘道夫】MapReduce实现矩阵乘法--实现代码

之前写了一篇分析MapReduce实现矩阵乘法算法的文章:[甘道夫]Mapreduce实现矩阵乘法的算法思路 为了让大家更直观的了解程序执行,今天编写了实现代码供大家参考. 编程环境: java version "1.7.0_40" Eclipse Kepler Windows7 x64 Ubuntu 12.04 LTS Hadoop2.2.0 Vmware 9.0.0 build-812388 输入数据: A矩阵存放地址:hdfs://singlehadoop:8020/wordsp

验证矩阵乘法

如何使用随机性矩阵乘法,随机算法在验证多项式的恒等问题比确定算法要快,而且在准确性上面也是可以接受的.假设有A,B,C三个n*n的矩阵.为了方便起见假定对模2的整数计算.我们想要快速的验证AB=C.首先想到的方法就是通过矩阵计算AB得到的矩阵与矩阵C对比.但是简单的矩阵乘法的时间复杂度为O(n^3),就算是经过优化的矩阵乘法算法的时间复杂度为O(n^2.37).显然这样的时间复杂度不为我们所接受. 我们可以再次使用随机算法来在一个可以接受的出错概率下来验证.算法首先抽取一个向量r=(r1,r2,

矩阵乘法的Strassen算法详解

题目描述 请编程实现矩阵乘法,并考虑当矩阵规模较大时的优化方法. 思路分析 根据wikipedia上的介绍:两个矩阵的乘法仅当第一个矩阵B的列数和另一个矩阵A的行数相等时才能定义.如A是m×n矩阵和B是n×p矩阵,它们的乘积AB是一个m×p矩阵,它的一个元素其中 1 ≤ i ≤ m, 1 ≤ j ≤ p. 值得一提的是,矩阵乘法满足结合律和分配率,但并不满足交换律,如下图所示的这个例子,两个矩阵交换相乘后,结果变了: 下面咱们来具体解决这个矩阵相乘的问题. 解法一.暴力解法 其实,通过前面的分析

BZOJ 1009 HNOI2008 GT考试 KMP算法+矩阵乘法

题目大意:给定长度为m的数字串s,求不包含子串s的长度为n的数字串的数量 n<=10^9 光看这个O(n)就是挂 我们不考虑这个 令f[i][j]为长度为i的数字串中最后j位与s中的前j位匹配的方案数 比如当s为12312时 f[i][3]表示长度为i,以123结尾且不包含子串"12312"的方案数 a[x][y]为f[i-1][x]转移至f[i][y]的方案数 换句话说(可能描述不清楚) a[x][y]为s的长度为x的前缀加上一个数字后 后缀可以与最长长度为y的前缀匹配 这个数

第四章 分治策略 4.2 矩阵乘法的Strassen算法

package chap04_Divide_And_Conquer; import static org.junit.Assert.*; import java.util.Arrays; import org.junit.Test; /** * 矩阵相乘的算法 * * @author xiaojintao * */ public class MatrixOperation { /** * 普通的矩阵相乘算法,c=a*b.其中,a.b都是n*n的方阵 * * @param a * @param b

算法导论-矩阵乘法-strassen算法

目录 1.矩阵相乘的朴素算法 2.矩阵相乘的strassen算法 3.完整测试代码c++ 4.性能分析 5.参考资料 内容 1.矩阵相乘的朴素算法 T(n) = Θ(n3) 朴素矩阵相乘算法,思想明了,编程实现简单.时间复杂度是Θ(n^3).伪码如下 1 for i ← 1 to n 2 do for j ← 1 to n 3 do c[i][j] ← 0 4 for k ← 1 to n 5 do c[i][j] ← c[i][j] + a[i][k]⋅ b[k][j] 2.矩阵相乘的stra

蓝桥杯- 算法训练 矩阵乘法

算法训练 矩阵乘法 时间限制:1.0s   内存限制:512.0MB 问题描述 输入两个矩阵,分别是m*s,s*n大小.输出两个矩阵相乘的结果. 输入格式 第一行,空格隔开的三个正整数m,s,n(均不超过200). 接下来m行,每行s个空格隔开的整数,表示矩阵A(i,j). 接下来s行,每行n个空格隔开的整数,表示矩阵B(i,j). 输出格式 m行,每行n个空格隔开的整数,输出相乘後的矩阵C(i,j)的值. 样例输入 2 3 21 0 -11 1 -30 31 23 1 样例输出 -3 2-8