题
流行的C ++库中的任何一个都有一个类(或类),使开发人员可以在不牺牲速度的情况下使用任意索引的数组?
为了使这个问题更具体的形式,我希望有可能编写类似于以下的代码:
//An array with indices in [-5,6)
ArbitraryIndicesArray<int> a = ArbitraryIndicesArray<int>(-5,6);
for(int index = -5;index < 6;++index)
{
a[index] = index;
}
解决方案
实际上,您应该使用具有偏移量的向量。甚至具有偏移的数组。额外的添加或减法对程序的执行速度不会有任何影响。
如果您想要具有与默认C数组完全相同的速度的东西,则可以将偏移量应用于数组指针:
int* a = new int[10];
a = a + 5;
a[-1] = 1;
但是,不建议这样做。如果您真的想这样做,则应使用隐藏可怕代码的内联函数创建包装类。您保持C代码的速度,但最终可以添加更多错误检查。
如评论中所述,更改数组指针后,您将无法使用该指针删除。您必须将其重置为数组的实际开始。替代方法是您始终将指针保持在开始,但可以与另一个修改的指针一起使用。
//resetting the array by adding the offset (of -5)
delete [] (a - 5);
其他提示
一个 std::vector<int>
会在这里解决问题。
向量中的单个元素的随机acss仅为o(1)。
如果您确实需要自定义索引,则可以根据向量进行自己的小型级别来应用偏好。
使用STL的地图类:
std::map<int, int> a;
for( int index = -5; index < 6; ++index )
{
a[index] = index;
}
地图在内部实现为排序容器,该容器使用二进制搜索来定位项目。
这是一个旧的线程,但出于参考清晰...
Boost.Multiarray 具有用于设置任何索引范围的扩展系统。
阵列 OBJEXXFCL 图书馆对任意索引范围有充分的支持。
这些都是多维数组库。对于OP 1D阵列需要std ::矢量包装器,就足够了。
回答是因为我不是很聪明。
包裹 std::vector
以及偏移到班级并提供 operator[]
:
template <class T>
class ArbVector
{
private:
int _offset;
std::vector<T> container;
public:
ArbVector(int offset) : _offset(offset) {}
T& operator[](int n) { return container[n + _offset] }
};
不确定这是否会编译,但是您明白了。
不要衍生 std::vector
不过,请参见评论。
不隶属于 StackOverflow