迭代std :: map的更好方法

时间:2012-10-09 15:27:04

标签: c++ stl

给定一张地图,我需要检索并操作两个立即存储的项目。 对我来说,处理矢量更容易,因为我可以做“iter + 1”或“iter - 1”。 对于地图,我运气不好。

例如,我给出一个简单的例子如下: 注意:在我的实际应用中,我不会简单地减去这些数字。

int main ()
{
    map<char,int> mymap;
    map<char,int>::iterator it;

    mymap['b'] = 100;
    mymap['a'] = 200;
    mymap['c'] = 300;

    // show content:
    map<char,int>::iterator firstItem  = mymap.begin();
    map<char,int>::iterator secondItem = ++mymap.begin();

    for ( ; secondItem != mymap.end(); ++firstItem, ++secondItem )
        cout << secondItem->second - firstItem->second << endl;

    return 0;
}

问题&GT;对此有更好的解决方案吗?

谢谢

6 个答案:

答案 0 :(得分:2)

不是在循环控件中递增两个迭代器(递增有点慢),而是分配firstItem = secondItem然后递增secondItem

答案 1 :(得分:2)

您可以使用单个迭代器完成此操作。将增量从标题移动到循环的中间,并在到达地图末尾时退出循环,如下所示:

map<char,int>::iterator item  = mymap.begin();
for (;;) {
    int first = item->second;
    ++item;
    if ( item == mymap.end()) break;
    cout << item->second - first << endl;
}

答案 2 :(得分:2)

如果地图为空,您当前的循环将显示未定义的行为

您的循环可以重写(更简单,并检查空地图),如下所示:

int main(int argc, char * argv[])
{
    map<char,int> mymap;
    map<char,int>::iterator it;

    mymap['b'] = 100;
    mymap['a'] = 200;
    mymap['c'] = 300;

    for ( it = ( mymap.begin() == mymap.end() ? mymap.end() : std::next(mymap.begin()) ) ; it != mymap.end(); ++it )
        cout << it->second - std::prev(it)->second << endl;

    return 0;
}

答案 3 :(得分:2)

这是一种风格问题。你可以这样做。

auto first = m.begin();

if (first != m.end())
{
    auto second = first;
    second++;

    for (; second != m.end(); first = second++)
    {
        ...        
    }
}

在地图为空的情况下,您也可以更优雅地进行救助。例如,您可以这样做:

if (m.empty()) return;

auto first = m.begin(), second = first;

for (second++; second != m.end(); first = second++)
{
   ...
}
如果可以的话,我会赞成后者,只有在必要时才使用前者。

答案 4 :(得分:1)

如果地图为空,您的代码将具有未定义的行为,但除此之外,它似乎是一种合理的方法,具体取决于您的总体目标。由于map迭代器不是随机访问,因此您不能只添加或减去一个,只能增加/减少。

另一种方法是制作迭代器的副本,然后在循环内递增。

答案 5 :(得分:0)

既不是更好,也不是更糟,只是另一种选择:

if (map.size() >=2)
std::accumulate(
  ++mymap.begin(),
  mymap.end(),
  mymap.begin(),
  [](mymap_type::const_iterator iprev, mymap_type::value_type const& entry)->mymap_type::const_iterator
  { 
    /* do something */;
    return ++iprev; 
  });