我有一个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 ++中这样的任意排序索引之间存储一些值的好方法是什么?
答案 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));