首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >可变数组表示

可变数组表示
EN

Stack Overflow用户
提问于 2011-03-31 08:26:22
回答 4查看 167关注 0票数 2

我在C++中遇到了一个问题,目前我还没有一个很好的解决方案。我收到的数据格式如下:

代码语言:javascript
运行
复制
typedef struct {
  int x;
  int y;
  int z;
}Data3D;

vector<Data3D> v; // the way data is received (can be modified)

但是,执行计算的函数接收的参数如下:

代码语言:javascript
运行
复制
Compute(int *x, int *y, int *z, unsigned nPoints)
{...}

是否有一种方法可以修改接收数据的方式( Data3D ),以便内存表示将从以下位置更改:

XYZXYZXYZ

XXXYYYZZZ

我正在寻找的是以类似的方式填充数据结构的方法--我们填充一个数组,但它具有上面的表示形式(XXXYYYZZZ)。欢迎任何自定义数据结构。

所以我想写一些类似的东西(在上面的例子中):

代码语言:javascript
运行
复制
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函数的声明而不更改其代码,因此也应该考虑到这一点。请参阅与涉及使用迭代器的解决方案相关的答案。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-03-31 08:55:31

你当然可以改变你的电脑功能。我假设在计算中对int*执行的所有操作都是取消引用和增量操作。

我没有测试它,但是你可以通过这样的结构

代码语言:javascript
运行
复制
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];
    }
};

并将其初始化为

代码语言:javascript
运行
复制
std::vector<Data3D> v;
IntIterator it(&v[0].x);

现在,您所需要做的就是更改计算函数参数的类型,它应该这样做。当然,如果使用的指针算法比它变得更复杂。

票数 2
EN

Stack Overflow用户

发布于 2011-03-31 08:42:04

基于迭代的解决方案

一个优雅的解决方案是让Compute()接受迭代器而不是指针。您提供的迭代器将有一个适当的++操作符(关于构建它们的简单方法,请参阅boost::iterator )。

代码语言:javascript
运行
复制
Compute(MyIterator x, MyIterator y, MyIterator z);

函数体通常很少进行更改,因为*xx[i]++x将由MyIterator处理以指向正确的内存位置。

快速污垢解

一个不那么优雅但更简单的解决方案是将数据保存在以下结构中

代码语言:javascript
运行
复制
typedef struct {
  std::vector<int> x;
  std::vector<int> y;
  std::vector<int> z;
}DataArray3D;

当接收到数据时,请填写您的结构如下

代码语言:javascript
运行
复制
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 (计算本身不变)

代码语言:javascript
运行
复制
Compute(&array.x[0], &array.y[0], &array.z[0]);
票数 3
EN

Stack Overflow用户

发布于 2011-03-31 08:40:31

合理的优雅(未进行汇编/测试):

代码语言:javascript
运行
复制
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工作。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5497100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档