我在C++中遇到了一个问题,目前我还没有一个很好的解决方案。我收到的数据格式如下:
typedef struct {
int x;
int y;
int z;
}Data3D;
vector<Data3D> v; // the way data is received (can be modified)但是,执行计算的函数接收的参数如下:
Compute(int *x, int *y, int *z, unsigned nPoints)
{...}是否有一种方法可以修改接收数据的方式( Data3D ),以便内存表示将从以下位置更改:
XYZXYZXYZ
至
XXXYYYZZZ
我正在寻找的是以类似的方式填充数据结构的方法--我们填充一个数组,但它具有上面的表示形式(XXXYYYZZZ)。欢迎任何自定义数据结构。
所以我想写一些类似的东西(在上面的例子中):
v[0].x = 1
v[0].y = 2
v[0].y = 0
v[1].x = 6
v[1].y = 7
v[1].z = 5并且具有下面的内存表示
1,6.2,7.0,5
1,6是x数组的开头。
2,7是y数组的开头。
0,5是z数组的开头。
我知道可以通过使用临时数组来解决这个问题,但是我想知道是否还有其他方法可以解决这个问题。
谢谢,
尤莲
稍后编辑:
由于有些解决方案只更改Compute函数的声明而不更改其代码,因此也应该考虑到这一点。请参阅与涉及使用迭代器的解决方案相关的答案。
发布于 2011-03-31 08:55:31
你当然可以改变你的电脑功能。我假设在计算中对int*执行的所有操作都是取消引用和增量操作。
我没有测试它,但是你可以通过这样的结构
struct IntIterator
{
int* m_currentPos;
IntIterator(int* startPos):m_currentPos(startPos){};
IntIterator& operator++()
{
m_currentPos += 3;
return *this;
}
IntIterator& operator++(int)
{
m_currentPos += 3;
return *this;
}
int operator*()
{
return *m_currentPos;
}
int& operator[](const int index)
{
return m_currentPos[index*3];
}
};并将其初始化为
std::vector<Data3D> v;
IntIterator it(&v[0].x);现在,您所需要做的就是更改计算函数参数的类型,它应该这样做。当然,如果使用的指针算法比它变得更复杂。
发布于 2011-03-31 08:42:04
基于迭代的解决方案
一个优雅的解决方案是让Compute()接受迭代器而不是指针。您提供的迭代器将有一个适当的++操作符(关于构建它们的简单方法,请参阅boost::iterator )。
Compute(MyIterator x, MyIterator y, MyIterator z);函数体通常很少进行更改,因为*x、x[i]或++x将由MyIterator处理以指向正确的内存位置。
快速污垢解
一个不那么优雅但更简单的解决方案是将数据保存在以下结构中
typedef struct {
std::vector<int> x;
std::vector<int> y;
std::vector<int> z;
}DataArray3D;当接收到数据时,请填写您的结构如下
void Receive(const Data3D& data, DataArray3D& array)
{
array.x.push_back(data.x);
array.y.push_back(data.y);
array.z.push_back(data.z);
}然后像这样调用Compute (计算本身不变)
Compute(&array.x[0], &array.y[0], &array.z[0]);发布于 2011-03-31 08:40:31
合理的优雅(未进行汇编/测试):
struct TempReprPoints
{
TempReprPoints(size_t size)
{
x.reserve(size); y.reserve(size); z.reserve(size);
}
TempReprPoints(const vector<Data3D> &v)
{
x.reserve(v.size()); y.reserve(v.size()); z.reserve(v.size());
for (size_t i = 0; i < v.size(); ++i ) push_back(v[i]);
}
void push_back(const Data3D& data)
{
x.push_back(data.x); y.push_back(data.y); z.push_back(data.z);
}
int* getX() { return &x[0]; }
int* getY() { return &y[0]; }
int* getZ() { return &z[0]; }
size_t size() { return x.size(); }
std::vector<int> x;
std::vector<int> y;
std::vector<int> z;
};因此,您可以用循环填充它,甚至尝试使用它来使std::back_inserter工作。
https://stackoverflow.com/questions/5497100
复制相似问题