Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 数组:将一维数组的索引转换为多维数组的向量索引_C++_Arrays_Multidimensional Array_Array Algorithms - Fatal编程技术网

C++ 数组:将一维数组的索引转换为多维数组的向量索引

C++ 数组:将一维数组的索引转换为多维数组的向量索引,c++,arrays,multidimensional-array,array-algorithms,C++,Arrays,Multidimensional Array,Array Algorithms,这将是一个很长的问题,请在阅读前深呼吸 我想了解将一维数组的索引转换为多维数组的向量索引的最快算法是什么 让我们通过一个例子来了解我为什么需要它: 我有一个二维数组:数组[i1][i2] i1从i1_b=0运行到i1_e=2 i2从i2_b=0运行到i2_e=1 因此,该数组逐行输出到文件中: 数组[0][0] 数组[0][1] 数组[0][2] 数组[1][0] 数组[1][1] 数组[1][2] 现在我逐行读取文件,索引k是最后读取的行数 我读取了第一行,它是数组[0][0],k=0 我读取

这将是一个很长的问题,请在阅读前深呼吸

我想了解将一维数组的索引转换为多维数组的向量索引的最快算法是什么

让我们通过一个例子来了解我为什么需要它:

我有一个二维数组:数组[i1][i2]

i1从i1_b=0运行到i1_e=2

i2从i2_b=0运行到i2_e=1

因此,该数组逐行输出到文件中:

数组[0][0]

数组[0][1]

数组[0][2]

数组[1][0]

数组[1][1]

数组[1][2]

现在我逐行读取文件,索引k是最后读取的行数

我读取了第一行,它是数组[0][0],k=0

我读取了第二行,即数组[0][1],k=1

可以注意到,k将从k_b=0运行到k_e=5,并且

k=0将对应于i1=0,i2=0

k=1将对应于i1=0,i2=1

问题:所以我的问题是如何以最快的方式将k转换成i1和i2? (我在读取文件时不需要它,但稍后在我的程序中)

在本例中,解决方案之一是

i1=k/(i1_e-i1_b+1)

i2=k%(i1_e-i1_b+1)

问题1:就周期和计算机时间而言,这是最快的解决方案吗

嗯。 问题2:我们如何将此算法推广到多维数组

数组[i1][i2][i3][i4]

i1=k/(i1_e-i1_b+1)

i2=k%(i1_e-i1_b+1)

i3=i2/(i1_e-i1_b+1)

i4=i2%(i1_e-i1_b+1)

问题3:这是最快的方法吗

问题4:相关问题是模除、整数除、整数相加和整数乘法的延迟是多少?如果这些数字取决于架构,请同时告诉我

提前谢谢

附言。 对于某些人来说,把这个问题看作是将秒转换为天-小时-秒的最快算法可能更容易

问题2:我们如何将此算法推广到多维数组

如果你有一个数组
arr[dim_1][dim_2]…[dim_n]
,你就有了这个等式

k = i_1*(dim_2*...*dim_n) + i_2*(dim_3*...*dim_n) + ... + i_{n-1}*dim_n + i_n
  = i_1*(dim_2*...*dim_n) + r_2
所以
i_1=k/(dim_2*.dim_n)
r_2=k%(dim_2*.dim_n)
,然后

i_2 = r_2 / (dim_3*...*dim_n) and r_3 = r_2 % (dim_3*...*dim_n)
等等,

直到找到
i\u n=r\u n

问题3:这是最快的方法吗

如果维度在编译时已知,则可以用乘法、移位和加法/减法替换除法。在许多体系结构上,这比除法指令快。在其他人身上,不是

但是,只有当您在该数组中做了大量的索引工作,而不是做其他工作时,才值得考虑

问题4:相关问题是模除、整数除、整数相加和整数乘法的延迟是多少?如果这些数字取决于架构,请同时告诉我


这些数字取决于体系结构和处理器。

请查看下面我将如何在C++1x中实现这一点,我希望这会有用。 干杯

#包括
#包括
#包括
/*将数组逐元素流到ostream*/
模板

尽管真正的问题是,这是否重要;你分析过吗?@nightcracker:有时候你的要求是尽可能快的。并不是所有的代码都是简单的UI,小的延迟是没有意义的。我不时地做一些图像处理代码。现在速度足够快,可以满足我们的要求。然而,如果/当我对如何使其更快有了想法,我会的,因为使这些算法更快会使我们的软件明显更快,从而使其更好。我不是想说你错了,他当然应该。然而,在我看来,OP要求的是尽可能快的解决方案,这是不同的。@nightcracker在我的特殊情况下,时间不是问题,但EdS明白我的意思-我只想知道在我未来的所有代码中是否存在最快的解决方案谢谢你的回答!我只剩下一个问题:你提供的回答问题2的算法是否最快?我很好奇,因为我想所有的程序员都需要“转换索引”,所以应该有“最著名的解决方案”,或者至少要调查这个“最佳解决方案”是否存在以及它依赖于什么。通常,转换留给编译器,而另一种方式是访问
arr[i1][i2][i3]
转换为
基地址+(i1*(d2*d3)+i2*d3+i3)*大小(元素类型)
。如果维度在编译时已知,编译器应该找到转换的最快方法。这是否意味着使用这种形式并插入常量
d2*d3
等作为编译时计算的文本,或者根据拉霍纳规则对其进行计算,这可能取决于,但根本没有更快的方法。从偏移量到索引元组要难得多,我不知道还有比除法更快的方法。。。。。。但在我有经验的硬件上,如果维度是静态已知的,则将除法转换为移位、乘法和加法的速度要快得多。当然,如果所有维度都是2的幂,那绝对是最好的情况,那么你只需要变换和遮罩。非常感谢你的帮助,谢谢你详尽而清晰的回答!
i_j = r_j / (dim_{j+1}*...*dim_n) and r_{j+1} = r_j % (dim_{j+1}*...*dim_n)
#include <iostream>
#include <array>
#include <algorithm>


/* stream arrays element by element to ostream */
template<size_t N, typename T>
std::ostream& operator<<(std::ostream& os, std::array<T, N> const&  obj)
{
  os << "{ ";
  for(auto a:obj)std::cout << a << " ";
  std::cout << "}";

  return os;
}

//end of recursion
template<size_t DIM, size_t I>
constexpr typename std::enable_if< (I==DIM), void  >::type
get_indexes(unsigned int index, std::array<unsigned int, DIM> const& depths, std::array<unsigned int,DIM>& indexes)
{}

//begin of the recursion
template<size_t DIM, size_t I=0>
constexpr typename std::enable_if< (I<DIM), void  >::type
get_indexes(unsigned int index, std::array<unsigned int, DIM> const& depths, std::array<unsigned int,DIM>& indexes)
{
    unsigned int  factor    =  1;
    for(unsigned int i=I+1; i<DIM; i++) factor *=depths[i];
    indexes[I]  =  index/factor;
    unsigned int next_index =  index%factor;
    get_indexes<DIM, I+1>(next_index, depths, indexes );
}

//some testing with 3 dimensions 
int main()
{
  constexpr unsigned ndimensions=3;
  std::array<unsigned int, ndimensions> depths{2, 3, 4};
  unsigned int nboxes = 1;

  for(unsigned int i =0; i< ndimensions; i++)nboxes *=depths[i];

  std::array<unsigned int, ndimensions> indexes;

  for(size_t i=0; i<nboxes; i++)
  {

    get_indexes<ndimensions>(i,depths ,  indexes);
    std::cout << i << " -> " <<indexes<< std::endl; 
  }


return 0;
}