C++ 在c++;stl映射,删除具有重复值的条目
假设map mymap有条目C++ 在c++;stl映射,删除具有重复值的条目,c++,dictionary,stl,C++,Dictionary,Stl,假设map mymap有条目 <'a', 111> <'b', 567> <'c', 956> <'d', 222> <'e', 111> <'f', 222> <'h', 222> <'i', 492> 等等…… 如何删除映射中重复值的条目。 e、 g.键“a”和“e”的值为111。因此,保留“a”的地图条目并删除“e”的条目 对于值222,保留条目“d”并删除条
<'a', 111>
<'b', 567>
<'c', 956>
<'d', 222>
<'e', 111>
<'f', 222>
<'h', 222>
<'i', 492>
等等……如何删除映射中重复值的条目。
e、 g.键“a”和“e”的值为111。因此,保留“a”的地图条目并删除“e”的条目
对于值222,保留条目“d”并删除条目“f”和“h”。
我正在寻找空间和时间复杂度尽可能高的解决方案您可能需要这样的解决方案:
#include <iostream>
#include <map>
#include <set>
int main() {
std::map<char, int> mymap
{
{'a', 111}, {'b', 567}, {'c', 956}, {'d', 222},
{'e', 111}, {'f', 222}, {'h', 222}, {'i', 492},
};
std::set<int> existingvalues;
for (auto it = mymap.begin(); it != mymap.end(); it++)
{
if (existingvalues.find(it->second) != existingvalues.end())
mymap.erase(it--); // value already encountered => remove entry
else
existingvalues.insert(it->second); // value not yet encountered => remeber it
}
for (auto it = mymap.begin(); it != mymap.end(); it++)
std::cout << "<'" << it->first << "', " << it->second << ">\n";
}
#包括
#包括
#包括
int main(){
std::map mymap
{
{'a',111},{'b',567},{'c',956},{'d',222},
{'e',111},{'f',222},{'h',222},{'i',492},
};
std::设置现有值;
for(auto it=mymap.begin();it!=mymap.end();it++)
{
if(existingvalues.find(it->second)!=existingvalues.end()
mymap.erase(它--);//已遇到值=>删除条目
其他的
existingvalues.insert(it->second);//尚未遇到的值=>记住它
}
for(auto it=mymap.begin();it!=mymap.end();it++)
std::cout您可能想要这样的东西:
#include <iostream>
#include <map>
#include <set>
int main() {
std::map<char, int> mymap
{
{'a', 111}, {'b', 567}, {'c', 956}, {'d', 222},
{'e', 111}, {'f', 222}, {'h', 222}, {'i', 492},
};
std::set<int> existingvalues;
for (auto it = mymap.begin(); it != mymap.end(); it++)
{
if (existingvalues.find(it->second) != existingvalues.end())
mymap.erase(it--); // value already encountered => remove entry
else
existingvalues.insert(it->second); // value not yet encountered => remeber it
}
for (auto it = mymap.begin(); it != mymap.end(); it++)
std::cout << "<'" << it->first << "', " << it->second << ">\n";
}
#包括
#包括
#包括
int main(){
std::map mymap
{
{'a',111},{'b',567},{'c',956},{'d',222},
{'e',111},{'f',222},{'h',222},{'i',492},
};
std::设置现有值;
for(auto it=mymap.begin();it!=mymap.end();it++)
{
if(existingvalues.find(it->second)!=existingvalues.end()
mymap.erase(它--);//已遇到值=>删除条目
其他的
existingvalues.insert(it->second);//尚未遇到的值=>记住它
}
for(auto it=mymap.begin();it!=mymap.end();it++)
这是一个有趣的问题,如果有点离题的话
由于映射的值是可散列且相等可比的,因此我们可以在线性时间内执行此操作,使用无序集
确定之前是否见过该值:
这段代码是c++17:
void comb(std::map<char, int>& themap)
{
std::unordered_set<int> seen;
seen.reserve(themap.size());
// iterate through the map in key order...
auto current = begin(themap);
const auto last = end(themap);
while(current != last)
{
auto&&[key, value] = *current;
// try to insert the value into the 'seen' set.
if (seen.insert(value).second)
// if we succeeded, then we're the first ocurrence of the
// value so move to next node
++current;
else
// otherwise, erase this node and move to the next
// (idiomatic method)
current = themap.erase(current);
}
}
void梳(标准::映射和主题映射)
{
std::看到无序的_集;
seen.reserve(themap.size());
//按键顺序遍历映射。。。
自动电流=开始(themap);
const auto last=结束(themap);
while(当前!=上次)
{
自动&&[键,值]=*当前;
//尝试将值插入“已看到”集合。
如果(见。插入(值)。秒)
//如果我们成功了,那么我们就是第一个出现这种情况的人
//值,以便移动到下一个节点
++电流;
其他的
//否则,请删除此节点并移动到下一个节点
//(惯用方法)
当前=映射擦除(当前);
}
}
这是一个有趣的问题,虽然有点离题
由于映射的值是可散列且相等可比的,因此我们可以在线性时间内执行此操作,使用无序集
确定之前是否见过该值:
这段代码是c++17:
void comb(std::map<char, int>& themap)
{
std::unordered_set<int> seen;
seen.reserve(themap.size());
// iterate through the map in key order...
auto current = begin(themap);
const auto last = end(themap);
while(current != last)
{
auto&&[key, value] = *current;
// try to insert the value into the 'seen' set.
if (seen.insert(value).second)
// if we succeeded, then we're the first ocurrence of the
// value so move to next node
++current;
else
// otherwise, erase this node and move to the next
// (idiomatic method)
current = themap.erase(current);
}
}
void梳(标准::映射和主题映射)
{
std::看到无序的_集;
seen.reserve(themap.size());
//按键顺序遍历映射。。。
自动电流=开始(themap);
const auto last=结束(themap);
while(当前!=上次)
{
自动&&[键,值]=*当前;
//尝试将值插入“已看到”集合。
如果(见。插入(值)。秒)
//如果我们成功了,那么我们就是第一个出现这种情况的人
//值,以便移动到下一个节点
++电流;
其他的
//否则,请删除此节点并移动到下一个节点
//(惯用方法)
当前=映射擦除(当前);
}
}
这里是另一个可能的解决方案,它涉及到在映射容器中迭代2次,如果存在重复值,则第二次迭代的元素将更少:
#include <iostream>
#include <algorithm>
#include <map>
template <typename T, typename U>
void RemoveDuplicateValues(std::map<T, U> &m)
{
std::map<U, T> tmp;
std::for_each(m.rbegin(), m.rend(), [&tmp](auto const &p)
{
tmp[p.second] = p.first;
});
m.clear();
for (auto const &p : tmp)
m[p.second] = p.first;
}
int main()
{
std::map<char, int> m
{
{ 'a', 111 },{ 'b', 567 },{ 'c', 956 },{ 'd', 222 },
{ 'e', 111 },{ 'f', 222 },{ 'h', 222 },{ 'i', 492 }
};
RemoveDuplicateValues(m);
// test
for (auto const &p : m)
std::cout << p.first << " " << p.second << std::endl;
return 0;
}
下面是另一个可能的解决方案,它涉及到在映射容器中迭代2次,如果存在重复的值,则第二次迭代的元素将更少:
#include <iostream>
#include <algorithm>
#include <map>
template <typename T, typename U>
void RemoveDuplicateValues(std::map<T, U> &m)
{
std::map<U, T> tmp;
std::for_each(m.rbegin(), m.rend(), [&tmp](auto const &p)
{
tmp[p.second] = p.first;
});
m.clear();
for (auto const &p : tmp)
m[p.second] = p.first;
}
int main()
{
std::map<char, int> m
{
{ 'a', 111 },{ 'b', 567 },{ 'c', 956 },{ 'd', 222 },
{ 'e', 111 },{ 'f', 222 },{ 'h', 222 },{ 'i', 492 }
};
RemoveDuplicateValues(m);
// test
for (auto const &p : m)
std::cout << p.first << " " << p.second << std::endl;
return 0;
}
我投票结束这个问题,因为SO不是一个代码编写服务。请显示您的努力构造一组值,如果该值已经在集合中,请从地图中删除该条目。~10-12行代码。“所以保留“a”的地图条目,删除“e”的条目”--为什么?为什么不保留“e”的映射条目并删除“a”的映射条目?您想要的规则也需要成为您问题的一部分。@hvd我想他想保留具有最低键的条目,但您是对的,这应该在question@MichaelWalz“最低”在ASCII中,也需要在以下问题中解释:在大多数C++实现中,代码< > b '< a '/c> >,但这可能是或不可能是OP。我投票将这个问题关闭为非主题,因为这不是一个代码编写服务。请显示您的努力构建一组值,如果值是已在集合中,请从地图中删除条目。~10-12行代码。“因此,保留“a”的地图条目,删除“e”的条目”--为什么?为什么不保留“e”的映射条目并删除“a”的映射条目?您想要的规则也需要成为您问题的一部分。@hvd我想他想保留具有最低键的条目,但您是对的,这应该在question@MichaelWalz“最低”也不太明确,所以需要在ASCII中解释:),在大多数C++实现中,<代码> b’< a ' /COD>,但这可能对OP.来说是不可取的,也可能不是。