C++<14环境下N维数组(如5D/6D)的索引与坐标互转实现咨询
N维数组坐标与ID互转的C++<14实现(基于3D逻辑扩展)
需求背景
现有3D坐标与ID互转的C代码,需扩展为支持任意N维(如5维、6维)的互转逻辑,且必须采用C<14标准实现。
原3D代码逻辑分析
原代码核心逻辑是维度权重的累加与分解:
- 坐标转ID:高维坐标乘以低维尺寸的累乘积,依次累加得到唯一ID
- ID转坐标:从高维到低维,用ID除以对应低维累乘积得到当前维度值,剩余部分继续分解低维
通用N维实现方案
以下实现兼容任意维度,基于C98/11/13标准(均满足C<14要求),提供动态维度(std::vector)和编译期固定维度(std::array)两种版本。
1. 动态维度版(适配运行时可变维度)
坐标转ID
#include <vector> #include <cassert> inline int coord2Id(const std::vector<int>& coord, const std::vector<int>& dims) { assert(coord.size() == dims.size() && "坐标与维度尺寸数量不匹配"); int id = 0; int multiplier = 1; // 初始为最低维的权重(对应原3D中x的权重1) // 从最高维到最低维遍历累加 for (int i = coord.size() - 1; i >= 0; --i) { assert(coord[i] >= 0 && coord[i] < dims[i] && "坐标分量超出对应维度范围"); id += coord[i] * multiplier; multiplier *= dims[i]; } assert(id >= 0 && id < multiplier && "计算得到的ID超出总元素范围"); return id; }
ID转坐标
#include <vector> #include <cassert> inline std::vector<int> id2Coord(int id, const std::vector<int>& dims) { assert(id >= 0 && "ID不能为负数"); std::vector<int> coord(dims.size()); int total_elements = 1; for (int dim : dims) { total_elements *= dim; } assert(id < total_elements && "ID超出总元素范围"); int remaining = id; int current_step = total_elements; // 从最高维到最低维分解ID for (int i = dims.size() - 1; i >= 0; --i) { current_step /= dims[i]; coord[i] = remaining / current_step; remaining = remaining % current_step; assert(coord[i] >= 0 && coord[i] < dims[i] && "分解得到的坐标分量非法"); } return coord; }
2. 编译期固定维度版(性能更优)
如果维度数量是编译期已知的,可使用std::array替代std::vector,避免动态内存开销:
#include <array> #include <cassert> template <size_t N> inline int coord2Id(const std::array<int, N>& coord, const std::array<int, N>& dims) { int id = 0; int multiplier = 1; for (int i = N - 1; i >= 0; --i) { assert(coord[i] >= 0 && coord[i] < dims[i]); id += coord[i] * multiplier; multiplier *= dims[i]; } assert(id >= 0 && id < multiplier); return id; } template <size_t N> inline std::array<int, N> id2Coord(int id, const std::array<int, N>& dims) { std::array<int, N> coord; int total_elements = 1; for (int dim : dims) { total_elements *= dim; } assert(id >= 0 && id < total_elements); int remaining = id; int current_step = total_elements; for (int i = N - 1; i >= 0; --i) { current_step /= dims[i]; coord[i] = remaining / current_step; remaining = remaining % current_step; assert(coord[i] >= 0 && coord[i] < dims[i]); } return coord; }
使用示例(兼容原3D逻辑)
以原3D场景为例,维度尺寸为mesh_dim_x、mesh_dim_y、mesh_dim_z:
// 动态维度版 std::vector<int> dims = {NoximGlobalParams::mesh_dim_x, NoximGlobalParams::mesh_dim_y, NoximGlobalParams::mesh_dim_z}; // ID转坐标 std::vector<int> coord = id2Coord(123, dims); int x = coord[0], y = coord[1], z = coord[2]; // 坐标转ID std::vector<int> target_coord = {x, y, z}; int id = coord2Id(target_coord, dims);
关键注意事项
- 维度顺序必须严格对应:
dims的第i个元素必须是coord第i个分量的尺寸上限 - 输入合法性:ID需小于总元素数,坐标分量需小于对应维度尺寸(代码中用
assert做检查,生产环境可替换为业务错误处理逻辑)
内容的提问来源于stack exchange,提问作者TheDarknesS
相关产品推荐
相关产品推荐

