我可以通过整数索引访问c ++ std :: map中的元素吗?

时间:2011-08-02 21:52:10

标签: c++ dictionary iterator openmp stdmap

我有一个我想要迭代的元素图。当然,标准的方法是使用for循环

for (map<string, int> iterator it = myMap.begin(); it != myMap.end(); ++it) {
    string thisKey = it->first;
    int thisValue = it->second;
}

但是如果我尝试使用OpenMP的 parallel for 构造使这个循环并行运行,它就不起作用了,这显然是一个已知的问题,因为它不能识别这种类型循环结构。

所以,我的备份计划是使用整数索引迭代器,并按索引访问键和值列表,就像我在C#中所做的那样:

for (int i = 0; i < myMap.Count; ++i) {
    string thisKey = myMap.Keys[i];
    string thisValue = myMap.Values[i];
}

...但我似乎无法在C ++中找到一个等效的方法。有没有办法在C ++中做到这一点,我不知道?

2 个答案:

答案 0 :(得分:7)

我对OpenMP一无所知,所以我不知道它是否会优化以下内容。但您可以使用std::advance,如下所示:

#include <map>
#include <string>
#include <iterator>
#include <iostream>

typedef std::map<std::string, int> Map;

int main() {
  Map m;
  m["one"] = 1;
  m["two"] = 2;
  for(int i = 0; i < m.size(); ++i) {
    Map::iterator it = m.begin();
    std::advance(it, i);
    std::string thiskey = it->first;
    int thisValue = it->second;
    std::cout << thiskey << "\n";
  }
}

但要注意std::advance是O(n),所以你的(单线程)复杂度是O(n ^ 2)。

<小时/> 编辑:如果您将地图元素复制到矢量,请意识到您可以在一个声明中执行此操作:

std::vector<Map::value_type> v(m.begin(), m.end());

因此:

#include <map>
#include <string>
#include <iterator>
#include <iostream>
#include <vector>

typedef std::map<std::string, int> Map;

int main() {
  Map m;
  m["one"] = 1;
  m["two"] = 2;
  int i = 0;
  for( std::vector<Map::value_type> v(m.begin(), m.end());
    i < v.size(); ++i) {
    std::string thiskey = v[i].first;
    int thisValue = v[i].second;
    std::cout << thiskey << "\n";
  }
}

答案 1 :(得分:5)

以下是一些相对无痛的选项。

  1. 为数组访问保留std::vectorstd::deque,以及单独的值映射。确保它们一致的腿部工作是你的问题。

  2. 使用boost::multi_index确保两个索引结构之间的一致性。作为警告,使用此选项的编译时间相当长。如果你走这条路,请考虑使用the pimpl idiom

  3. 我没有使用OpenMP的经验,所以我不能推测这些选项中的任何一个在实践中是否值得。