You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 08:25:19