如何实现删除一个std::map<int,int>中值为3的所有元素的函数?
如何实现删除一个std::map<int,int>中值为3的所有元素的函数?
说明,本题为腾讯c++面试题
[解决办法]
找到并删除之
#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 都失效了, 还自增啊!
这样写:for (iter = m.begin(); iter != m.end(); ) { if (iter -> second == 3) m.erase(iter++); else ++iter;}
[解决办法]
for (curr = mapii.begin(); curr != mapii.end(); ) { if (curr->second == 3) { curr = mapii.erase(curr); } else { ++curr; } }
[解决办法]
for (curr = mapii.begin(); curr != mapii.end(); ) { if (curr->second == 3) { mapii.erase(curr++); } else { ++curr; }}
[解决办法]
// 设it为map<int,int>的迭代器对象,mii为map<int,int>对象;// 以下代码删除所有value为3的元素while((it = std::find(mii.begin(), mii.end(), 3)) != mii.end()){ mii.erase(it);}
[解决办法]
写个例子.
#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到括号中一样。