将数据存储在具有可互换x / y坐标的2d矩阵中

时间:2018-01-26 01:53:07

标签: c++ arrays

我有一个C ++中的节点列表,我希望在某种数据结构中存储每对节点之间的距离dist

例如,5个节点:(0,1,2,3,4)

我想存储每个人之间的距离。 我可以将它们存储在2d矩阵中,但随后我将存储冗余数据。

存储节点1和3之间距离的

dist[1][3]将保持与dist[3][1]相同的值

此外,dist[0][0]dist[1][1]dist[2][2],..不需要,也浪费数据。

我认为1d数组具有将[x] [y]坐标映射到数组索引的映射函数,但在重新访问代码时可能会变得难以阅读和理解。

在C ++中这样的任意排序索引之间存储一些值的好方法是什么?

1 个答案:

答案 0 :(得分:0)

正确的抽象是class,它为您包装数据。

#include <algorithm>
#include <array>

template <typename TNumber, std::size_t Dimension>
class triangular_matrix
{
public:
    // It's common/friendly to make a value_type for containers
    using value_type = TNumber;

    // Overloading operator() is fairly common and looks pretty decent
    value_type operator()(std::size_t row, std::size_t col) const
    {
        return _data.at(index_of(row, col));
    }

    // A non-const overload allows users to edit using regular assignment (=)
    value_type& operator()(std::size_t row, std::size_t col)
    {
        return _data.at(index_of(row, col));
    }

private:
    // You're storing 1 less than the dimensions
    static constexpr stored_dim = Dimension - 1;

    // Use sum of arithmetic series:
    static constexpr data_size = stored_dim / 2U;

    static std::size_t index_of(std::size_t row, std::size_t col)
    {
        // I'm not sure what you want to do for this case -- you said these
        // indexes aren't needed, but I don't know if you mean they won't be
        // accessed or what...so just throw!
        if (row == col)
            throw std::invalid_argument("row and column can't be the same!");

        // flip
        if (row > col)
            std::swap(row, col);

        // This is probably not the fastest way to do this...
        --row;
        std::size_t index = 0U;
        for (; row > 0U; --row)
            index += row;
        return index + col;
    }

    // Store using a flat array
    std::array<TNumber, data_size> _data;
};

用法如下:

triangular_matrix<double, 4> m;
m(1, 3) = 5.2;
m(2, 1) = 9.1;
assert(m(2, 1) == m(1, 2));