将一种类型的STL对象存储到另一种类型的有效方法

时间:2013-03-13 05:17:24

标签: c++

我有一个STL对象,例如

std::vector <long> vec1;

我希望将其转换为矢量

std::vector <int> vec2;

使用

std::map<long,int>map;

是否有一种有效的方法可以动态删除映射到vec2的vec1元素,从而减少vec1的大小?该算法应该消耗最少的内存并且应该很快。是否可以就地执行此操作? std :: remove_if会做得好吗?如何将性能与分块处理相比较,即vec1被分成多个块;然后将每个块映射并存储在vec2中;在此之后,chunk将从内存中删除。

vec1(和vec2)也可以是一个向量(向量的向量)。

3 个答案:

答案 0 :(得分:1)

如果您已有地图,可以试试这个(C ++ 11)解决方案:

std::vector<long> vec1;  // Original vector
std::map<long, int> map; // How to map the `long` value to an `int`

std::vector<int> vec2;  // The destination vector

for (const auto l : vec1)
    vec2.push_back(map[l]);

如果第一个向量是向量向量,只需使用嵌套循环:

for (const auto& v : vec1)
{
    for (const auto l : v)
        vec2.push_back(map[l]);
}

答案 1 :(得分:1)

  

是否有一种有效的方法可以动态删除映射到vec2的vec1元素,从而减少vec1的大小?

vector的开头删除内容效率很低,因为它会导致其余元素向前移动以填充开头的空白区域。并且在向量末尾释放的内存无论如何都不会返回到堆中,因为它是一个大内存块的所有部分,一次性释放。

此处更合适的是std::queue默认情况下使用std::deque数据结构。这包括一系列小存储块。您可以使用pop开始释放内存。

#include <queue>

std::queue <long> vec1;
std::queue <int> vec2;

while ( ! vec1.empty() ) {
    vec2.push( value_map[ vec1.front() ] );
    vec1.pop();
}

您也可以直接使用std::deque个对象。然后,您将使用push_frontpop_back。这是一个非常酷的课程;它保持了“平坦”对象序列的错觉,即使它们不是vector使用的整体扁平数组。

答案 2 :(得分:0)

您可以在将源矢量复制到目标矢量时从源矢量中删除元素。

while (!source.empty()) {
  destination.push_back(map[source.back()]);
  source.pop_back();
}

这需要O( n log m )时间和O(1)空间,其中<​​em> n 是source.size()和< em> m 是map.size()