首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

怎么实现删除一个std:地图<int,int>中值为3的所有元素的函数

2012-08-21 
如何实现删除一个std::mapint,int中值为3的所有元素的函数?如何实现删除一个std::mapint,int中值为3的

如何实现删除一个std::map<int,int>中值为3的所有元素的函数?
如何实现删除一个std::map<int,int>中值为3的所有元素的函数?
说明,本题为腾讯c++面试题

[解决办法]
找到并删除之

C/C++ code
#include <iostream>#include <map>using namespace std;int main(void){    int i;    map<int, int> mapii;    map<int, int>::iterator curr;    for (i = 0; i < 10; i++)        mapii[i] = i % 3 + 1;    cout << "=====" << endl;    for (curr = mapii.begin(); curr != mapii.end(); ++curr)        cout << curr->first << " : " << curr->second << endl;    for (curr = mapii.begin(); curr != mapii.end(); ++curr) {        if (curr->second == 3) {            mapii.erase(curr);            if (++curr == mapii.end())                break;        }    }    cout << "=====" << endl;    for (curr = mapii.begin(); curr != mapii.end(); ++curr)        cout << curr->first << " : " << curr->second << endl;    return 0;}/* output:=====0 : 11 : 22 : 33 : 14 : 25 : 36 : 17 : 28 : 39 : 1=====0 : 11 : 23 : 14 : 26 : 17 : 29 : 1*/
[解决办法]
mapii.erase(curr);
if (++curr == mapii.end()) // curr 都失效了, 还自增啊!

C/C++ code
这样写:for (iter = m.begin(); iter != m.end(); ) {    if (iter -> second == 3)         m.erase(iter++);    else        ++iter;}
[解决办法]
探讨
to mymtom:

iter的副本 进入 erase 前 iter 本身就已经完成了自增,此时 iter 仍然有效!

[解决办法]
C/C++ code
    for (curr = mapii.begin(); curr != mapii.end(); )     {        if (curr->second == 3)         {            curr = mapii.erase(curr);        }        else        {            ++curr;        }    }
[解决办法]
C/C++ code
for (curr = mapii.begin(); curr != mapii.end(); ) {    if (curr->second == 3)     {        mapii.erase(curr++);    }    else    {        ++curr;    }}
[解决办法]
探讨

楼上几位让我无语。
首先 map<>::erase 是没有返回值的。
其次, m.erase (iter++); 相当于 iter_copy = iter; ++ iter; m.erase (iter_copy);
迭代器自增可是一个函数调用!

[解决办法]
C/C++ code
// 设it为map<int,int>的迭代器对象,mii为map<int,int>对象;// 以下代码删除所有value为3的元素while((it = std::find(mii.begin(), mii.end(), 3))      != mii.end()){    mii.erase(it);}
[解决办法]
写个例子.
C/C++ code
#include <set>#include <vector>#include <map>using namespace std;template<class T>class CTestStl{public:    void OnTestUseRet()    {        T::iterator It = m_Data.begin();        for (; It != m_Data.end();)        {            It = m_Data.erase(It);        }    }    void OnTestUsePp()    {        T::iterator It = m_Data.begin();        for (; It != m_Data.end();)        {            m_Data.erase(It++);        }    }    T& GetData(){ return m_Data;}private:    T m_Data;};int main(){    CTestStl< map<int,int> > oTestStlMap;    oTestStlMap.GetData()[1] = 1;    oTestStlMap.GetData()[2] = 1;    oTestStlMap.GetData()[3] = 1;    oTestStlMap.GetData()[4] = 1;    oTestStlMap.OnTestUseRet();    oTestStlMap.GetData()[1] = 1;    oTestStlMap.GetData()[2] = 1;    oTestStlMap.GetData()[3] = 1;    oTestStlMap.GetData()[4] = 1;    oTestStlMap.OnTestUsePp();    CTestStl< set<int> > oTestStlSet;    oTestStlSet.GetData().insert(1);    oTestStlSet.GetData().insert(2);    oTestStlSet.GetData().insert(3);    oTestStlSet.GetData().insert(4);    oTestStlSet.OnTestUseRet();    oTestStlSet.GetData().insert(1);    oTestStlSet.GetData().insert(2);    oTestStlSet.GetData().insert(3);    oTestStlSet.GetData().insert(4);    oTestStlSet.OnTestUsePp();    CTestStl< multiset<int> > oTestStlMultiset;    oTestStlMultiset.GetData().insert(1);    oTestStlMultiset.GetData().insert(1);    oTestStlMultiset.GetData().insert(2);    oTestStlMultiset.GetData().insert(2);    oTestStlMultiset.OnTestUseRet();    oTestStlMultiset.GetData().insert(1);    oTestStlMultiset.GetData().insert(1);    oTestStlMultiset.GetData().insert(2);    oTestStlMultiset.GetData().insert(2);    oTestStlMultiset.OnTestUsePp();    CTestStl< multimap<int,int> > oTestStlMultimap;    oTestStlMultimap.GetData().insert(make_pair(1,1));    oTestStlMultimap.GetData().insert(make_pair(1,1));    oTestStlMultimap.GetData().insert(make_pair(2,1));    oTestStlMultimap.GetData().insert(make_pair(2,1));    oTestStlMultimap.OnTestUseRet();    oTestStlMultimap.GetData().insert(make_pair(1,1));    oTestStlMultimap.GetData().insert(make_pair(1,1));    oTestStlMultimap.GetData().insert(make_pair(2,1));    oTestStlMultimap.GetData().insert(make_pair(2,1));    oTestStlMultimap.OnTestUsePp();    CTestStl< vector<int> > oTestStlVector;    oTestStlVector.GetData().push_back(1);    oTestStlVector.GetData().push_back(2);    oTestStlVector.GetData().push_back(3);    oTestStlVector.GetData().push_back(4);    oTestStlVector.OnTestUseRet();    oTestStlVector.GetData().push_back(1);    oTestStlVector.GetData().push_back(2);    oTestStlVector.GetData().push_back(3);    oTestStlVector.GetData().push_back(4);    oTestStlVector.OnTestUsePp();    return 0;} 


[解决办法]
去除一个容器中有特定值的所有对象: 
如果容器是vector、string或deque,使用erase-remove惯用法。

如果容器是list,使用list::remove。

如果容器是标准关联容器,使用它的erase成员函数。

去除一个容器中满足一个特定判定式的所有对象: 
如果容器是vector、string或deque,使用erase-remove_if惯用法。

如果容器是list,使用list::remove_if。

如果容器是标准关联容器,使用remove_copy_if和swap,或写一个循环来遍历容器元素,当你把迭代器传给erase时记得后置递增它。

在循环内做某些事情(除了删除对象之外): 
如果容器是标准序列容器,写一个循环来遍历容器元素,每当调用erase时记得都用它的返回值更新你的迭代器。

如果容器是标准关联容器,写一个循环来遍历容器元素,当你把迭代器传给erase时记得后置递增它。

COPY 《effective stl》 item9
[解决办法]
个人观点:《effective stl》 item9提倡的应该是一种好的编程习惯。就像一个函数没有形参时,加void到括号中一样。

热点排行