C++ 如何将M维数组转换为N维数组?
受到C++ 如何将M维数组转换为N维数组?,c++,arrays,algorithm,templates,multidimensional-array,C++,Arrays,Algorithm,Templates,Multidimensional Array,受到arr2D[i][j]和arr1D[i*k+j]的启发,在阅读了相关内容及其下面的注释后,我想知道一种可以更改任何数组维数的算法 让我试着把它形式化: 输入: 一个M多维容器A 容器的尺寸D(尺寸) 目标维度N 输出: 如果N>0则返回与A内容相同的N维容器B,否则返回错误代码 注意: 您可以为N维容器选择任何最佳大小 编辑: 我不需要任何完全工作的代码。我在问是否有任何算法可以做到这一点?将[100]转换为[10][10]: #include <iostream> typed
arr2D[i][j]
和arr1D[i*k+j]
的启发,在阅读了相关内容及其下面的注释后,我想知道一种可以更改任何数组维数的算法
让我试着把它形式化:
输入:
M
多维容器A
D
(尺寸)N
N>0
则返回与A
内容相同的N维容器B
,否则返回错误代码
注意:
您可以为N维容器选择任何最佳大小
编辑:
我不需要任何完全工作的代码。我在问是否有任何算法可以做到这一点?将[100]转换为[10][10]:
#include <iostream>
typedef int (*parray)[10];
parray foo (int *in) {
return (parray)in;
}
int main()
{
int in[100];
in[55] = 42;
int (*out)[10] = foo(in);
std::cout << out[5][5] << std::endl;
return 0;
}
#包括
typedef int(*parray)[10];
帕雷福(整数*整数){
返回(帕雷)在;
}
int main()
{
int in[100];
in[55]=42;
int(*out)[10]=foo(in);
std::cout您的原始M
-多维容器是A
我们想创建一个新的N
多维容器B
,它将保存a
的所有内容
首先,我们必须找出一个映射,我们可以在a
和B
中轻松找到相同的元素
让我们使用一些示例来推断映射是如何实现的:
(1)M=2,N=1
A: a * b B: c
we can set the dimension c to be a * b, thus we have
A[i][j] = B[i * c + j]
(2)M=3,N=1
A: a * b * c B: d
d = a * b * c
A[i][j][k] = B[(i * b * c) + (j * c) + k]
(3)M=3,N=2
A: a * b * c B: d * e
d = a, e = b * c
A[i][j][k] = B[i][j * c + k]
(4)M=4,N=1
A: a * b * c * d B: e
e = a * b * c * d
A[i][j][k][l] = B[(i * b * c * d) + (j * c * d) + (k * d) + l]
(5)M=5,N=4
A: a * b * c * d * e B: u * v * w * x
u = a, v = b, w = c, x = d * e
A[i][j][k][l][m] = B[i][j][k][(l * e) + m]
(6)M=5,N=2
A: a * b * c * d * e B: f * g
f = a, g = b * c * d * e
A[i][j][k][l][m] = B[i][(j * c * d * e) + (k * d * e) + (l * e) + m]
如果A有M个维度a1,a2,…,aM,B有N个维度b1,b2,…,bN,我们可以说:
如果M>N,则对于所有0
这样我们就知道了如何创建B以及B的每个维度的大小
使用示例中所示的映射功能,您可以轻松地将任何M
-维度矩阵转换为N
-维度矩阵
如果M
,您可以做相同的事情,但方向相反。因为您不需要代码,让我解释一下如何使用模板来完成
假设你有一个大小为n{0},…,n{D-1}的D维数组,你总是可以通过将其中两个数组的大小相乘来删除一个维度。例如:a[5][4][3]包含60个元素,因此b[20][3]或c[5][12](对于简单的情况,因为你甚至可以构造D[15][4]和任何置换)可以很容易地包含与a相同的元素,索引的映射也很明显
现在使用C++做它更复杂,但你需要:可变模板和模板元编程。
变量模板用于定义任意维的数组类型,模板元编程用于定义将D维数组映射到N维数组的运算符。(我可以说这并不容易,但却是模板元编程中一个非常困难的好练习).因此,您只需在不更改任何数据的情况下重新格式化矩阵。正如我在评论中所暗示的,最简单的方法是使用1D数组中间步骤将M维转换为N维
这里的其他答案都在同一条轨道上,但缺乏完整的数学知识……它们只是一些小维度的例子,没有通用方程,所以这里是:
要在A[A0][A1]…[A(M-1)]
和X[A0*A1*…*A(M-1)]
之间转换,其中A0,A1,….A(M-1)
是容器的尺寸(分辨率),只需执行以下操作:
// M-D -> 1D
x = a0
+a1*A0
+a2*A0*A1
...
+a(M-1)*A0*A1*...*A(M-2);
// 1D -> M-D
q=x;
a0 = q%A0; q/=A0;
a1 = q%A1; q/=A1;
a2 = q%A2; q/=A2;
...
a(M-1) = q%A(M-1); q/=A(M-1);
其中a0,a1,…a(M-1)
和x
是数组中的索引
实际上,您不需要将M-D数组转换为1D,然后再转换回N-D,只需转换索引即可:
for(a0=0;a0
我认为这类似于将数字表示从一个基数转换为另一个基数。每个维度的唯一区别是基数不同。例如,您可以将十进制数字1234视为四维数组中的索引,其中每个维度的大小为10。要显示任何代码吗?显示您迄今为止尝试过的内容。出于实际目的,只需模板包装器对线性<代码> STD::向量<代码>提供X维访问应该足够,只有当向量的大小必须不同时,该问题是什么。@ AdtEngDeCuffi在C++中添加了答案……至少打破了严格的混叠规则,所以UB。我仍然无法理解这一点,也许是Type和函数。你能解释一下吗?正如@Jarod指出的,你不想这样做,除非是作为一个练习。它是使用强制转换将100个整数从100x1重新映射到10x10。数组只是隐藏在引擎盖下的地址算术。哦,我明白了@stark谢谢。你知道这个问题为什么会有反对票吗?不知道。我有点惊讶我没有投反对票等等,如果M有k个因子,N>k怎么办?M[a][b]可以简单地投影到M[1][1][a][b],不是吗?是的@jean baptisteyunès。我一直在寻找一种最佳的方法。你展示了一个微不足道的解决方案,但我想知道这是否也是最佳的解决方案?你所说的最佳是什么意思?最后,机器中的一切都是平的,因此这只是一个利用坐标索引线性结构的问题。哦@jean baptisteyunès,我没有想一想。我会对你的回答投赞成票。如果M有k个因子,N>k呢?因子你指的是维度?在我的回答中,已经有了解释。如果M
的维度小于N
,你只需在相反的方向做同样的事情。这种方法对任何一角都是最佳的M
和N
.ig的扩展,所以我不能完全理解它,因为格式和一些精简的解释添加了一些示例,希望如此
A0*A1*...*A(M-1) <= B0*B1*...*B(N-1)