【问题标题】:Slicing a C-array creating a C++ vector, keeping only 2 elements every 3切片一个 C 数组创建一个 C++ 向量,每 3 个元素只保留 2 个元素
【发布时间】:2016-10-04 13:42:49
【问题描述】:

我有一个这样的 C 数组:

int X[]={0, 1, 2, 3, 4, 5, 6, 7, 8};

我需要从这个数组中创建两个 stl 向量,方法是切片,可能共享最多的内存并减少深度副本。 第一个向量 Y 必须只包含 0-th 和第一个元素,每三个元素,例如在这种情况下,这个新向量 Y 将包含

std::vector<int> Y; // contains: [0,1,3,4,6,7]

另一个向量 Z 必须包含原始数组中的每个第三个元素:

std::vector<int> Z; // contains [2,5,8]

第一个基于 for 循环的解决方案如下:

vector<int> Y,Z;
for (int i=0; i<9;i+=3)
{
    Y.push_back(*(X+i));
    Y.push_back(*(X+i+1));
    Z.push_back(*(X+2));
}

但我很确定,通过自定义迭代器,问题可能会得到更有效的解决方案。无论如何,是否有其他更快的版本在此数组上实现 ma​​sk-view 以避免生成副本?

【问题讨论】:

  • 有什么具体问题吗?
  • 我不认为有一种方法可以使用自定义迭代器来做到这一点而不会过度设计。
  • 我看不出自定义迭代器如何使您的简单 for 循环更“高效”(尽管您可以使用一些 .reserves)en.wikipedia.org/wiki/KISS_principle
  • 除了使用 reserve() 之外,我怀疑你能得到比这更有效的方法。
  • @LightnessRacesinOrbit:“简化,然后添加亮度”不是更适合您吗:-)

标签: c++ object-slicing


【解决方案1】:

你的意思可能是这样的:

#include <iostream>
#include <vector>
using namespace std;

struct MyIndexing {
    int* original;
    MyIndexing(int* o) : original(o) {}
    int& getY(int index){ return original[0]; /* to be done... */ }
    int& getZ(int index){ return original[(index+1)*3 -1]; }
};

int main() {
    int X[]={0, 1, 2, 3, 4, 5, 6, 7, 8};
    MyIndexing mi(X);
    for (int i=0;i<3;i++){ std::cout << mi.getZ(i) << " "; }
    return 0;
}

打印:

2  5  8

它不会创建向量,但无论如何您的要求有点矛盾。要么避免复制,要么创建新的向量。两者都不可能。

【讨论】:

    【解决方案2】:

    如果您必须创建向量,则必须复制数据,因为向量数据是连续的。

    如果您不需要向量,您可以创建 2 个接口(请原谅我的 C# 术语,但我认为它适用),一个为 Y 数据提供 getter,一个为 X 数据提供;实现,扩展这两个接口可以隐藏你的数据在一个向量中的事实。

    【讨论】:

    • 事实如此。但是,在我想象的大多数情况下,这样的界面使用起来效率很低。尽管如此,这似乎确实是OP(现在)要求的,后期编辑。不过,您并没有真正提供解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 2012-10-04
    • 2021-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多