c++ - 在C++中使用1-d索引数组访问n-d数组元素的更好方法?

标签 c++ arrays pointers grammar

最近,我正在做一些有关C ++指针的事情,当我想使用包含索引的一维数组访问多维数组中的元素时遇到了这个问题。

假设我有一个数组arr,这是一个4维数组,所有元素都设置为0,除了arr[1][2][3][4]1,还有一个数组idx,其中每个维度都包含arr的索引,我可以使用arr[idx[0]][idx[1]][idx[2]][idx[3]]或使用*(*(*(*(arr + idx[0]) + idx[1]) + idx[2]) + idx[3])来访问此元素。

n很大时会出现问题,这不是很好,所以我想知道是否有更好的方法来进行多维访问?

#include <bits/stdc++.h>
using namespace std;

#define N 10

int main()
{
    int arr[N][N][N][N] = {0};
    int idx[4] = {1, 2, 3, 4};
    arr[1][2][3][4] = 1;
    cout<<"Expected: "<<arr[1][2][3][4]<<" at "<<&arr[1][2][3][4]<<endl;
    cout<<"Got with ****: ";
    cout<<*(*(*(*(arr + idx[0]) + idx[1]) + idx[2]) + idx[3])<<endl;
    return 0;
}


输出

Expected: 1 at 0x7fff54c61f28
Got with ****: 1

最佳答案

构造用于索引多维数组的算法的方式将根据选择的语言而有所不同。您已经用C和C ++标记了这个问题。我会坚持使用后者,因为我的答案与C ++有关。一段时间以来,我一直在研究类似但又不同的东西,因此在构建多功能多维矩阵类模板时,这成为一个有趣的问题。

我发现有关多维向量和矩阵的较高级别的问题是,在理解较高维的性质时,3的阶数会重复产生奇迹。在考虑其算法软件实现方面之前,请从几何角度考虑这一点。

从数学上讲,让我们考虑第一个形状为0维对象的最低维度0。碰巧是该点可以具有无限数量的坐标位置属性的任意点。点p0(0),p1(1),p2(2,2),p3(3、3、3),... pn(n,n,... n)指向每个对象具有定义数量的维度属性的特定语言环境。这意味着在任何方向或尺寸上都没有线性距离(例如长度,宽度或高度),相反,没有此形状或大小范围的形状或物体没有定义任何面积,体积或体积的较大尺寸的线性距离。同样对于这些0维点,也没有方向感,这也意味着没有定义大小的旋转角。要考虑的另一件事是,任意点也是零向量。有助于理解这一点的另一件事是通过使用代数多项式,使得线性的f(x) = mx+b是一维方程,形状(在这种情况下为线)或图形,f(x) = x^2是二维,f(x) = x^3是三维,f(x) = x^4是四维,依此类推,直到f(x) = x^n都是N维。在将两个不同的点关联起来以给您指定方向上的至少1个线段或向量之前,无法定义长度或大小,旋转的方向或角度,面积,体积等。隐含方向后,便会出现倾斜。

在数学运算中,最简单的就是加法,它仅是线性平移,一旦您介绍了加法,您还将介绍所有其他运算,例如减法,乘法,除法,幂和部首。一旦有了乘法和除法,就可以定义旋转,旋转角度,面积,体积,变化率,斜率(也就是切线函数),从而定义几何形状和三角函数,进而得出积分和导数。是的,我们都上过数学课,但是我认为这对于理解如何建立一个数量级与另一个数量级的关系非常重要,一旦您知道如何建立一个数量级的关系,这将有助于我们轻松地处理高次元数量级。构造它。一旦您了解甚至更高阶的运算也不过是加法和减法的扩展,您将开始了解到它们的连续运算本质上仍是线性的,只是它们扩展到了多个维度。

早些时候,我说过3的次序反复出现奇迹,所以让我解释一下我的意思。因为我们每天都从3D角度感知事物;我们只能可视化3个彼此正交的不同向量,从而为您提供自然的3维空间,例如“左”和“右”,“向前和向后”为您提供水平轴和平面,以及“向上和向下”为您提供垂直轴和平面。我们无法可视化任何更高的内容,因此我们无法可视化x^4, x^5, x^6 etc...数量级的维度,但它们确实存在。如果我们开始查看数学多项式的图,我们可以开始看到奇数和偶数函数之间的模式,其中x^4, x^6, x^8相似,而它们仅是x^2的展开,而x^5, x^7 & x^9的函数仅是比x^3的扩展。因此,我认为前几个维度是正常的:零-点,第一个-线性,第二个-区域和第三个-体积,至于第4个及更高维度,我都将它们称为体积。

因此,如果您看到我使用“体积”,则它直接与第3维有关,而如果我指的是“体积”,则它与第3维以上的任何维有关。现在让我们考虑一个矩阵,您已经在常规代数中看到了,其中常见矩阵由MxN定义。嗯,这是一个具有M * N元素的二维平面矩阵,该矩阵的面积也为M * N。让我们扩展到更高维度的矩阵,例如MxNxO,这是一个具有M * N * O元素的3D矩阵,现在具有M * N * O体积。因此,当您形象地将MxN 2D零件视为书的页面时,O组件代表书的每一页或一盒盒子。这些矩阵的元素可以是任何值,从简单值到应用运算,方程,方程组,集或仅是存储容器中的任意对象。因此,现在当我们有一个四阶矩阵(例如MxNxOxP)时,它现在具有第4维维度,但是可视化此问题的最简单方法是,这将是一维数组或向量,其中所有元素将是体积P的3D矩阵。现在,当您拥有MxNxO矩阵时,您将拥有一个MxNxOxPxQ的2D面积矩阵,其中每个元素都是一个PxQ体积矩阵。再一次,如果您有一个MxNxO,则现在有一个6维矩阵,而这次您有一个3D体积矩阵,其中每个MxNxOxPxQxR元素实际上都是PxQxR的3D矩阵。而且,一旦您越走越高,此模式便会重复并再次合并。因此,任意矩阵的行为顺序是重复这些维:1D是线性向量或矩阵,2D是面积或平面矩阵,而3D是体积矩阵,更高的东西会重复此过程,从而压缩体积的前一步,因此使用术语体积矩阵。看一下这张桌子:

// Order of Magnitude And groupings     
-----------------------------------
Linear         Area          Volume
x^1            x^2           x^3
x^4            x^5           x^6
x^7            x^8           x^9
x^10           x^11          x^12
...            ...           ...
----------------------------------


现在只需要使用一点微积分就可以知道将哪个数量级索引到哪个更高维度上。一旦知道了特定的维,就可以很容易地采用多个导数来给出线性表达式。然后遍历空间,然后积分到多个导数的相同阶数以得出结果。首先应忽略高维顺序中最小有效的较低维,这将消除大量的中间工作。如果您要处理的尺寸为12维,则可以假定定义第一组体积的前3个维是紧紧包装的,这是另一个3D体积矩阵的元素,然后再一次,二维矩阵本身就是一个元素另一个3D体积矩阵。因此,我们有一个重复的模式,现在只需要将其用于构造算法,一旦有了算法,就可以了。以任何可编程语言实现这些方法应该非常容易。因此,您可能需要进行3种情况下的切换,才能确定使用哪种算法方法,即了解矩阵或nd数组的整体维数,其中一个处理线性量级,另一个处理线性量级,最后一个处理体积量,如果最终量为4th +那么整个过程本质上是递归的。

关于c++ - 在C++中使用1-d索引数组访问n-d数组元素的更好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43108141/

相关文章:

c - 指向结构和打印的指针

c++ - 如何在我的项目中包含常量

c++ - g++中的优化级别-O3危险吗?

c++ - Photoshop如何将两张图片融合在一起?

c++ - x86 MASM - 传递和访问二维数组

c - 带有指向函数指针的结构

c++ - 从 C++ 函数返回指针或引用

C++ 派生类无法正常运行

ios - 如何唯一标识 UITableView 中的每个单元格

具有非 size_t 整数的 std::array 的 C++ 模板参数推导