提问人:Sarcana 提问时间:7/22/2023 最后编辑:ks1322Sarcana 更新时间:7/22/2023 访问量:79
使用对向量作为unordered_map [已关闭]
Use a vector of pairs as an unordered_map [closed]
问:
我最初使用unordered_map来存储某个数字出现的频率,然后使用priority_queue来实现最大堆,以获得出现次数最多的第一个元素。但是unordered_map没有保留插入顺序,我正在考虑为此使用对向量。
我之前尝试过实现这一点,但是由于vector<int,int>不是我需要使用的有效模板,因此我可以简单地计算频率。我怎样才能计算出其中元素的频率?
我尝试将find与一对向量一起使用,并尝试了和.如果这些似乎不起作用,我如何找到该元素并更改其频率值?unordered_map<int,int>mp
mp[element]++
vector<pair<int,int>> vec
if(find(vec.begin().first,vec.end().first,node)==vec.end().first)
if(find(vec.first.begin(),vec.first.end(),node)==vec.first.end())
答:
1赞
Vlad from Moscow
7/22/2023
#1
使用效率低下。使用会好得多.std::vector
std::map
但是,如果要使用向量并且它是未排序的,那么您需要使用标准算法。std::find_if
这是一个演示程序,展示了如何做到这一点。
#include <iostream>
#include <utility>
#include <vector>
#include <iterator>
#include <algorithm>
int main()
{
std::vector<std::pair<int, int>> v;
for (auto key : { 1, 2, 3, 4, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 1 })
{
auto present = [=]( const auto &p ) { return p.first == key; };
auto pos = std::find_if( std::begin( v ), std::end( v ), present );
if (pos == std::end( v ))
{
v.emplace_back( key, 1 );
}
else
{
++pos->second;
}
}
for ( const auto &p : v )
{
std::cout << p.first << ": " << p.second << '\n';
}
return 0;
}
程序输出为
1: 2
2: 5
3: 4
4: 3
5: 1
0赞
fabian
7/22/2023
#2
您可能只想跟踪 in a 中的插入顺序。您可能需要为此编写一个包装器类型。std::unordered_map
std::vector<std::unordered_map<...>::value_type*>
template<class Key, class Value>
class MyMap
{
using Map = std::unordered_map<Key, Value>;
using Entry = std::unordered_map<Key, Value>::value_type;
using ConstEntry = std::add_const_t<Entry>;
Map m_map;
std::vector<typename Map::value_type*> m_insertionOrder;
public:
auto& operator[](Key const& key)
{
auto insertResult = m_map.try_emplace(key);
if (insertResult.second)
{
try
{
m_insertionOrder.push_back(&*insertResult.first);
}
catch (...)
{
m_map.erase(key);
throw;
}
}
return insertResult.first->second;
}
template<bool isConst>
class IteratorImplementation
{
std::vector<typename Map::value_type*>::const_iterator m_pos;
public:
using value_type = std::conditional_t<isConst, ConstEntry, Entry>;
using reference = value_type&;
using difference_type = void;
using pointer = value_type*;
using iterator_category = std::forward_iterator_tag;
IteratorImplementation(std::vector<typename Map::value_type*>::const_iterator pos) noexcept
: m_pos(pos)
{
}
bool operator==(IteratorImplementation const& other) const noexcept
{
return m_pos == other.m_pos;
}
bool operator!=(IteratorImplementation const& other) const noexcept
{
return m_pos != other.m_pos;
}
reference operator*() const
{
return **m_pos;
}
pointer operator->() const
{
return *m_pos;
}
IteratorImplementation& operator++()
{
++m_pos;
return *this;
}
IteratorImplementation operator++(int)
{
IteratorImplementation result = *this;
++(*this);
return result;
}
};
auto begin() const noexcept
{
return IteratorImplementation<true>(m_insertionOrder.begin());
}
auto end() const noexcept
{
return IteratorImplementation<true>(m_insertionOrder.end());
}
};
int main()
{
std::vector<int> values;
for (int i = 0; i <= 25; ++i)
{
values.push_back(i);
}
for (int i = 25; i >= 0; i -= 2)
{
values.push_back(i);
}
MyMap<int, int> map;
for (auto e : values)
{
++map[e];
}
for (auto [key, value] : map)
{
std::cout << key << " -> " << value << '\n';
}
auto maxElement = std::max_element(map.begin(), map.end(), [](std::pair<const int, int> const& v1, std::pair<const int, int> const& v2)
{
return v1.second < v2.second;
});
std::cout << "max: " << maxElement->first << '\n';
}
评论
std::vector<int>