Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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++ 根据世界位置在1D数组中查找通用项?_C++_Arrays_Multidimensional Array - Fatal编程技术网

C++ 根据世界位置在1D数组中查找通用项?

C++ 根据世界位置在1D数组中查找通用项?,c++,arrays,multidimensional-array,C++,Arrays,Multidimensional Array,我有一个数据数组(通用vertexdata)。我需要能够根据位置搜索数组元素。目前,每个顶点元素都记录自己的位置,我只需使用for循环搜索每个元素并比较位置。我必须在我的程序中经常这样做,这对性能相当关键。在每一个元素中循环似乎真的非常低效 使用C++、BTW. 我的问题是:有没有更好的办法?也就是说,是否有一种直接基于3D位置访问必要元素的方法?这些位置是整数,因此可能会有所帮助 我曾想过简单地使用3D数组(即顶点[256][256][256]),但我负担不起浪费的内存,因为只有大约30-50

我有一个数据数组(通用vertexdata)。我需要能够根据位置搜索数组元素。目前,每个顶点元素都记录自己的位置,我只需使用
for循环
搜索每个元素并比较位置。我必须在我的程序中经常这样做,这对性能相当关键。在每一个元素中循环似乎真的非常低效

使用C++、BTW.</P> 我的问题是:有没有更好的办法?也就是说,是否有一种直接基于3D位置访问必要元素的方法?这些位置是整数,因此可能会有所帮助

我曾想过简单地使用3D数组(即顶点[256][256][256]),但我负担不起浪费的内存,因为只有大约30-50%的顶点位置实际上包含一个顶点。也许这可以通过指针来实现?他们在未分配时是否使用内存


3D阵列的另一个问题是顶点可以分布在几乎无限的区域,这将形成非常非常大的阵列。此外,顶点是动态地有效添加的,这意味着它们可以添加到一个可以考虑使用稀疏网格作为ADT的解决方案。

std::unordered_映射是一个散列映射,可用于创建稀疏网格数据结构。如果为3d向量编写一个好的散列,可以获得非常好的O(1)读取性能,这将接近原始数组的性能

散列映射还允许您使用“几乎无限”区域(当然,约束将在底层数据类型中)


抱歉耽搁了

对于无序地图,这是一个很好的信息资源:

我在自己的项目中使用了一对int实现,但我确信它可以用于三维坐标

namespace std {
    template <class T>
    inline void hash_combine(std::size_t & seed, const T & v) {
        std::hash<T> hasher;
        seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 
    }

    template<> struct hash<pair<int, int> > {size_t operator()(pair<int, int> x) const { size_t seed=0; hash_combine(seed, x.first); hash_combine(seed, x.second); return(seed); } };
}
在此之后,您可以将该结构视为常规的
std::map

对于三维坐标,可以声明自己的结构

struct vector
{
    int i,j,k;
};
然后修改哈希函数(格式化为可读性)

模板结构哈希{
size_t运算符()(向量x)常量{
种子大小=0;
联合收割机(种子,x.i);
联合收割机(种子,x.j);
联合收割机(种子,x.k);
返回(种子);
}
};

<>代码> 一个解决方案,你可以考虑使用稀疏网格作为你的ADT.

std::unordered_map
是一个散列映射,可用于创建稀疏网格数据结构。如果为3d向量编写一个好的散列,可以获得非常好的O(1)读取性能,这将接近原始阵列的性能

散列映射还允许您使用“几乎无限”区域(当然,约束将在底层数据类型中)


抱歉耽搁了

对于无序地图,这是一个很好的信息资源:

我在自己的项目中使用了一对int实现,但我确信它可以用于三维坐标

namespace std {
    template <class T>
    inline void hash_combine(std::size_t & seed, const T & v) {
        std::hash<T> hasher;
        seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 
    }

    template<> struct hash<pair<int, int> > {size_t operator()(pair<int, int> x) const { size_t seed=0; hash_combine(seed, x.first); hash_combine(seed, x.second); return(seed); } };
}
在此之后,您可以将该结构视为常规的
std::map

对于三维坐标,可以声明自己的结构

struct vector
{
    int i,j,k;
};
然后修改哈希函数(格式化为可读性)

模板结构哈希{
size_t运算符()(向量x)常量{
种子大小=0;
联合收割机(种子,x.i);
联合收割机(种子,x.j);
联合收割机(种子,x.k);
返回(种子);
}
};

八叉树可能是基于体素的地形(或模型)的最佳解决方案。八叉树的基本概念由节点和叶组成。每个节点(和叶)表示立方体空间,每个节点包含8个子节点(或叶),每个子节点占用其父节点空间的1/8(请参阅)

叶与节点不同,它没有更多的子节点,而是包含数据本身——在您的例子中是顶点数组

八叉树的深度取决于您自己,它实际上取决于地形的详细程度。现在,如果您想将顶点组织到树上,对于每个顶点,您将首先将其发送到主节点(节点是树的根,即包含所有其他节点)然后根据位置确定顶点属于哪个子节点。然后递归地传递顶点,直到它到达存储在数组中的叶节点

为了简单起见,下面是带有四叉树的2D示例:

                (4,4)
-----------------
|   3   |   4   |
|       |       |
-----------------
|   1   |   2   |
|       |       |
-----------------
(0,0)
假设地形的大小为4x4。在本例中,我们仅使用主节点作为包含叶节点的节点。如果现在有顶点,则假设
(0.2,3.2)
。顶点被传递到根节点。由于
0.2<4/2
3.2>4/2
,该节点将顶点发送到存储顶点的3号叶。如果您在空间(或本例中的平面)中搜索位置,您将以与所述存储类似的方式执行此操作

在您的实现中,您可以使用指针表示节点的子节点/叶。如果您想优化空间,您根本不必存储每个节点的尺寸和位置,而是简单地说每个节点的尺寸是
1x1x1
,然后在传递它之前相应地变换每个顶点。 也就是说,您有大小为
1000x1000x1000
的地形和位于位置
(600600100)
的顶点。现在您将位置除以大小,得到位置
(0.6,0.6,0.1)
传递给节点。由于
0.6>1/2
0.1<1/2
您将相应地将其传递给节点,但在您将其转换之前,再次将其从高分量中减去1/2,然后将所有分量乘以2(因为子节点在所有维度中都较小两倍)以获得位置
(0.2,0.2,0.2)