在 c++ stl 映射中,删除具有重复值的条目
In c++ stl map, delete entries with duplicate values
考虑地图mymap有条目
<'a', 111>
<'b', 567>
<'c', 956>
<'d', 222>
<'e', 111>
<'f', 222>
<'h', 222>
<'i', 492>
等等...
如何删除映射中值重复的条目。
例如,键"a"和"e"的值为 111。因此,保留"a"的映射条目并删除"e"的条目
对于值 222,保留条目"d"并删除条目"f"和"h"。
我正在寻找具有最佳空间和时间复杂性的解决方案
这是一个有趣的问题,如果有点跑题的话。
由于映射的值是可哈希的且相等可比的,因此我们可以在线性时间内执行此操作,使用unordered_set
来确定该值之前是否见过:
这段代码是 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);
}
}
你可能想要这样的东西:
#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";
}
这是另一种可能的解决方案,涉及遍历 map 容器 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;
}
演示:https://ideone.com/oThy17
a 111
b 567
c 956
d 222
i 492
相关文章:
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 在C应用程序中运行C++(带有STL)函数
- 使用2个键的cpp-stl::优先级队列排序不正确
- 在STL容器中使用模板类
- 用C++中的CPerson(类)类型的对象初始化STL矢量
- 将stl字符串缩小到小于15个字符的容量
- 在为LINUX创建共享库时,如何避免STL的私有/弱副本
- 检查函数返回类型是否与STL容器类型值相同
- STL算法函数在多个一维容器上的使用
- 在STL - C++中按成绩对学生列表进行排序?
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- λ可以适应STL吗?
- 为什么使用 NDK 不能存在不同的 stl 实现?
- 如果我真的真的想从 STL 容器继承,并且我继承构造函数并删除新运算符,会发生什么?
- 使用 char 分隔符解析C++中的字符串,但将可重复的字符保留为每个解析的子字符串 (C++ STL) 中的分隔符
- 在C++中迭代 STL 集时出现奇怪的问题<CStudent>
- 如何在 C++17 STL 并行算法中处理调度?
- 在学习数据结构之前对STL有一个了解是好的吗?
- C++ STL 排序会检查 NaN 吗?