算法:多维数组的行优先和列优先
发布日期:2022-03-16 03:25:37 浏览次数:31 分类:技术文章

本文共 4545 字,大约阅读时间需要 15 分钟。

多维数组的行优先和列优先

由于计算机内存是一维的,多维数组的元素应排成线性序列后存入存储器。有两种存入方式

举个例子,对于数组:

在这里插入图片描述

如果我们按照C语言的方式存储它,也就是行有限存储的话,那么在内存中,它的形状是这样的:

在这里插入图片描述
另一派存储方式,也就是列优先存储,它的代表是Fortran语言。上面的数组在内存中的形状就是这样的了:
在这里插入图片描述

实现

C语言数组行优先实现

在这里插入图片描述

/*** @brief C语言 数组 行优先 实现*/#include 
#include
#include
#include
#define OK 1#define ERROR -1#define MAX_DIM 8 ///允许的最大数组维数typedef int ElemType;typedef struct{
ElemType *base; ///数组元素基址 int dim; ///数组维数 int *bounds; ///数组维界基址 int *constants; ///数组映像函数常量基址}Array; ///数组结构///数组方法声明int InitArray( Array *pArr, int nDim, ... ); ///初始化数组 pArrvoid DestroyArray( Array *pArr ); ///销毁数组 pArrint Locate( Array *pArr,va_list ap ); ///定位下标指向的元素在数组中的位置int Assign( Array *pArr, ElemType *elm, ... ); ///数组赋值int Value( Array *pArr, ElemType *elm, ... ); ///数组取值///数组方法实现/*** @brief 初始化数组* @param pArr 指向待初始化的数组* @param nDim 数组的维数* @param ... 数组各维数的长度* @return 初始化成功返回OK, 否则返回ERROR*//* * nDim = 2 * ... = (2, 5) * */int InitArray( Array *pArr, int nDim, ... ){
if( nDim < 1 || nDim > MAX_DIM ) return ERROR; ///初始化 pArr 数组维数属性 pArr->dim = nDim; ///构造数组维界基址 /* * pArr->bounds [2] * */ pArr->bounds = (int *)malloc( nDim * sizeof(int) ); if( !pArr->bounds ) return ERROR; int i = 0, nElemCount = 1; va_list ap; va_start( ap, nDim ); /* * 卝 卝 卝 卝 卝 * 卝 卝 卝 卝 卝 * nDim = 2 (2, 5) * pArr->bounds[0] = 2 * pArr->bounds[1] = 5 * nElemCount = 2 * 5 * */ for( i = 0; i < nDim; ++i ) {
int t = va_arg( ap, int ); pArr->bounds[i] = t; if( pArr->bounds[i] < 0 ) return ERROR; nElemCount *= pArr->bounds[i]; } va_end(ap); ///初始化元素基址 pArr->base = (ElemType *)malloc( nElemCount * sizeof(ElemType) ); if( !pArr->base ) return ERROR; ///初始化函数映像常数基址 pArr->constants = (int *)malloc( nDim * sizeof(int) ); ///递推求常量基址 pArr->constants[nDim-1] = 1; for( i = nDim -2 ; i >= 0; --i ) {
pArr->constants[i] = pArr->bounds[i+1] * pArr->constants[i+1]; } return OK;}/*** @brief 销毁数组 pArr** @param pArr 指向待销毁的数组*/void DestroyArray( Array *pArr ){
if( pArr->base ) free( pArr->base ); if( pArr->bounds ) free( pArr->bounds ); if( pArr->constants ) free( pArr->constants );}/*** @brief 定位数组下标指向的元素在数组中的位置** @param 指向的数组* @param ... 数组的下标 ** @return 若下标合法, 返回下标在数组中的位置, 否则返回 ERROR*/int Locate( Array *pArr, va_list ap ) // n 行 m 列{
int nPos = 0; for(int i = 0; i < pArr->dim; ++i ) //正确的维度 {
int ind = va_arg( ap, int ); ///使用断言, 确保下标合法 assert( ind >= 0 && ind < pArr->bounds[i] ); nPos += pArr->constants[i] * ind; } va_end(ap); return nPos;}/*** @brief 数组赋值** @param pArr 指向待赋值的数组* @param elm 指向赋值元素* @param nDim 数组维数* @param ... 数组下标** @param 赋值成功返回 OK, 否则返回 ERROR*/int Assign( Array *pArr, ElemType *elm, ... ){
va_list ap; va_start( ap, elm ); int nPos = Locate( pArr, ap ); *(pArr->base + nPos) = *elm; return OK;}/*** @brief 数组取值*/int Value( Array *pArr, ElemType *elm, ... ){
int nPos = 0; va_list ap; va_start( ap, elm ); nPos = Locate( pArr, ap ); *elm = *(pArr->base + nPos); return OK;}//测试int main1(){
Array arr; ///初始化一个三维数组, 大小为 2x3x5 InitArray( &arr, 2, 2, 3, 5 ); int a = 0; ///赋值测试 int i = 0, m = 0, n = 0; for( i = 0; i < 2; ++i ) for( m = 0; m < 3; ++m ) for( n = 0; n < 5; ++n ) {
a = i + m + n; Assign( &arr, &a, i, m, n ); } int b = 0; ///取值测试 for( i = 0; i < 2; ++i ) for( m = 0; m < 3; ++m ) for( n = 0; n < 5; ++n ) {
Value( &arr, &b, i, m, n ); printf( "[%d][%d][%d]=%d\n", i, m, n, b ); } ///销毁数组 DestroyArray( &arr ); return 0;}//测试int main(){
Array arr; ///初始化一个2维数组, 大小为 2x5 InitArray( &arr, 2, 2, 5); int a = 0; ///赋值测试 int i = 0, m = 0; for( i = 0; i < 2; ++i ){
for( m = 0; m < 5; ++m ){
a = i + m ; Assign( &arr, &a, i, m ); } } int b = 0; ///取值测试 for( i = 0; i < 2; ++i ) for( m = 0; m < 5; ++m ) {
Value( &arr, &b, i, m ); printf( "[%d][%d]=%d\n", i, m, b); } ///销毁数组 DestroyArray( &arr ); return 0;}

C语言数组列优先实现

转载地址:https://blog.csdn.net/zhizhengguan/article/details/122665504 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:分布式:如何实现分布式互斥
下一篇:算法:贪心算法

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年03月24日 15时17分53秒