C++ 迭代std::map的更好方法

C++ 迭代std::map的更好方法,c++,stl,C++,Stl,给定一张地图,我需要检索并操作两个立即存储的项目。 对我来说,研究向量更容易,因为我可以做iter+1或iter-1。 至于地图,我运气不好 例如,我举一个简单的例子如下: 注意:在我的实际应用程序中,我不会简单地减去这些数字 int main () { map<char,int> mymap; map<char,int>::iterator it; mymap['b'] = 100; mymap['a'] = 200; myma

给定一张地图,我需要检索并操作两个立即存储的项目。 对我来说,研究向量更容易,因为我可以做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;
}
问题>有更好的解决方案吗


谢谢

如果映射为空,那么代码将具有未定义的行为,但除此之外,这似乎是一种合理的方法,具体取决于您的总体目标。由于映射迭代器不是随机访问的,所以不能只加或减一个,只能加/减


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

如果映射为空,则代码将具有未定义的行为,但除此之外,这似乎是一种合理的方法,具体取决于您的总体目标。由于映射迭代器不是随机访问的,所以不能只加或减一个,只能加/减


另一种方法是复制迭代器,然后在循环中递增。

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

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

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

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

你可以用一个迭代器来完成。将增量从标题移动到循环的中间,并在到达地图末端时退出循环,如下所示:

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

如果映射为空,则当前循环将显示未定义的行为

可以更简单地重写循环,并检查空映射,如下所示:

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;
}

如果映射为空,则当前循环将显示未定义的行为

可以更简单地重写循环,并检查空映射,如下所示:

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;
}

这是风格问题。你能行

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++)
{
   ...
}

如果可以的话,我倾向于后者,只有在我必须的时候才使用前者。

这是风格的问题。你能行

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++)
{
   ...
}

如果可以的话,我倾向于后者,只有在我必须的时候才使用前者。

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

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; 
  });

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

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; 
  });

你想干什么?std::prev和std::next是否有帮助?选择容器类型取决于通用用例。如果你做了很多这种类型的迭代,并且你不介意支付搜索性能的代价,那么使用带有随机访问迭代器的容器可能是有意义的。@Cameron,很高兴了解这两个运算符,但这只适用于C++11。你想做什么?std::prev和std::next是否有帮助?选择容器类型取决于通用用例。如果你做了很多这种类型的迭代,并且你不介意支付搜索性能的代价,那么使用带有随机访问迭代器的容器可能是有意义的。@Cameron,很高兴了解这两个操作符,但它只适用于C++11。