算术在3D矢量中获取索引

Arithmetically getting index in 3D vector

本文关键字:获取 索引 3D      更新时间:2023-10-16

i具有结构的3D向量。我指结构由结构的I J和K在3D矢量中的位置。但是,当赚取数百万美元时,由于对象存储了大量数据,因此会占用大量内存。

我如何有效地弄清我,j,k一个特定的结构对象,而无需将这些信息存储在结构本身中。我可以用某种内存算术吗?

#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
    struct MyStruct {
        size_t i;
        size_t j;
        size_t k;
        bool some_bool;
    };
    vector<vector<vector<MyStruct>>> three_d_struct_v;
    size_t max_i = 1000000;
    size_t max_j = 10;
    size_t max_k = 10;
    for(size_t i = 0; i < max_i; i++) {
        for(size_t j = 0; j < max_j; j++) {
            for(size_t k = 0; k < max_k; k++) {
                three_d_struct_v.emplace_back(MyStruct{i,j,k,false});
            }
        }
    }

    return 0;
}

有一种非常简单的方法可以使用真实数组来执行此操作。多级std::vector<>不会做,因为所有不同行向量分配的内存不是连续的。但是,使用该语言的内置阵列,这很简单:

//Get the memory
bool myData* = new bool[max_i*max_j*max_k];
inline size_t getIndex(size_t i, size_t j, size_t k) { return (i*max_j + j)*max_k + k; }
inline size_t getI(size_t index) { return index/max_j/max_k; }
inline size_t getJ(size_t index) { return (index/max_k)%max_j; }
inline size_t getK(size_t index) { return index%max_k; }

现在,您可以以相同的方式谈论索引。如果您确实必须以C 方式执行此操作,则可以转换引用和索引:

bool& referenceToElement = myData[anIndex];
size_t recoveredIndex = &referenceToElement - myData;

但是,在C中,您可以做得更好:

bool (*myData)[max_j][max_k] = malloc(max_i*sizeof(*myData));
myData[i][j][k] = true;    //True 3D array access!

myData[i][j][k]执行的计算与上述C 中的myData[getIndex(i, j, k)]的计算完全相同。而且,像以前一样,您可以使用指针算术检索索引。

c 还具有多维数组,,但要求数组尺寸为编译时间常数(并且您需要使用new而不是malloc())。在C中,没有这样的限制,可以在运行时计算数组大小。

这是您想要的吗?您可以将m视为所有max_i * max_j * max_k结构的索引。

这是未经测试的。在size_t类型上调用div时,您可能必须进行一些铸造。

#include <cstdlib> // divmod
size_t max_i = 1000000;
size_t max_j = 10;
size_t max_k = 10;
size_t N = max_i * max_j * max_k; // beware of overflow
for( size_t m=0 ; m<N ; ++m )
{
    div_t q = div( m, max_k );
    size_t k = q.rem;
    q = div( q.quot, max_j );
    size_t j = q.rem;
    q = div( q.quot, max_i );
    size_t i = q.rem;
    // Now i, j, k are set. Do as thou shall.
}

在您的情况下,您可以通过存储最少的元数据来很容易地弄清楚这一点。

由于您有两个相对较小的向量,因此可以存储所有J/K组合的起始位置。

size_t max_i = 1000000;
size_t max_j = 10;
size_t max_k = 10;

您需要重组存储的向量[k] [j] [i]。如果将100个可能的J/K组合存储在STD :: MAP中,则可以通过找到小于向量的地址的最大地址来找到J/K值。从那里,您可以计算字节中的偏移,然后除以结构的大小以找出i。

如果max_j和max_k变得大。