问题描述:现在给定一个Map(hash_map),其key=string,value = int,string是唯一,value值可能相同,现在需要删掉map中所有value值相同的键值对,一个不留。
这个问题该则么解决呢?首先想到hashmap,而在c++11中引入了底层使用hash的map,它叫unordered_map。
我的解题思路是:
遍历一遍原map,使用额外一个map(名叫tmp,它的key=int,value=string),记录出现的键值对。遍历每个键值对的时候,先查找其value是否在tmp中存在,若存在,则直接删掉原map中的项;这个时候也说明原map中也可能存在多余的value值,所以我们需要理利用tmp的value(string),去查找原map中冲突的项目,若存在则删掉(这样就很好的解决了,删除不完全的情况),下面给出代码吧:
//#include <unordered_map>
void DelKVnode(unordered_map<string, int>& Um)
{
//注意tmp的key = int,value = string
unordered_map<int, string> tmp;
unordered_map<string, int>::iterator it = Um.begin();
//遍历一遍map就能实现删除所有value值相同的键值对(也就是删掉所有的value值相同的键值对)
while(it != Um.end())
{
//记录当前遍历节点的key,value
string key = it->first;
int value = it->second;
//在临时map中查找该节点的value值是否存在,若已存在则发生冲突
unordered_map<int,string>::iterator curit = tmp.find(value);
if (curit != tmp.end())
{
unordered_map<string, int>::iterator delit = it;
++it;
Um.erase(delit);
// 原来在Um中的没有删除的冲突的键值对也是需要删除的
if (Um.find(curit->second) != Um.end())
{
Um.erase(Um.find(curit->second));
}
}
else
{
//若没有在tmp中出现,则加入到tmp中
tmp.insert(pair<int, string>(value, key));
++it;
}
}
}
我简单的给了个测试用例:
void TestDelKV()
{
//unorder_map是防冗余
unordered_map<string, int> Um;
Um.insert(pair<string, int>("haa", 2));
Um.insert(pair<string, int>("ha", 2));
Um.insert(pair<string, int>("a", 4));
Um.insert(pair<string, int>("aa", 4));
Um.insert(pair<string, int>("aaa", 4));
unordered_map<string, int>::iterator it = Um.begin();
for (; it != Um.end(); ++it)
{
cout << it->first.c_str() << "," << it->second << ";";
}
DelKVnode(Um);
cout << endl;
it = Um.begin();
for (; it != Um.end(); ++it)
{
cout << it->first.c_str() << " " << it->second << endl;
}
}
现在感觉这个问题真的是豁然开朗,刚刚看到的时候确实不是很明白这个问题,可能是练得太少,一般都是使用map(RBtree),所以突然使用hash_map一时没缓过来,所以我还是需要多多练习,不仅要熟悉其底层构成,也需要学会熟练使用。