假设我有std::unordered_map<std::string, int>
代表一个单词以及单词出现在书中的次数,我希望能够按值对其进行排序。
问题是,我希望排序是稳定的,以便在两个项目具有相同值的情况下,我希望首先插入到地图中的那个是第一个。
通过添加将保持插入的time
的附加字段来实现它很简单。然后,创建一个同时使用time
和value
的comperator。使用简单的std::sort
会给我O(Nlog(N))
时间复杂度。
就我而言,只要时间可以改善,空间就不是问题。我想利用它并做一个桶分类。哪个应该给我O(N)
时间复杂度。但是当使用桶排序时,没有编译器,当迭代地图中的项时,订单不会被保留。
如何通过铲斗分类或其他方式使其稳定并仍保持O(N)
时间复杂度?
我想如果我有一些哈希映射在迭代时保留插入顺序,它将解决我的问题。
任何其他具有相同时间复杂度的解决方案都是可以接受的。
答案 0 :(得分:0)
以下是我使用std::unordered_map
提出的可能解决方案,并使用std::vector
跟踪插入顺序。
O(1)
时间复杂度。O(N)
O(N)
实施:
unordered_map<std::string, int> map;
std::vector<std::unordered_map<std::string,int>::iterator> order;
// Lets assume this is my string stream
std::vector<std::string> words = {"a","b","a" ... };
// Insert elements to map and the corresponding iterator to order
for (auto& word : words){
auto it = map.emplace(word,1);
if (!it.second){
it.first->second++;
}
else {
order.push_back(it.first);
}
max_count = std::max(max_count,it.first->second);
}
// Bucket Sorting
/* We are iterating over the vector and not the map
this ensures we are iterating by the order they got inserted */
std::vector<std::vector<std::string>> buckets(max_count);
for (auto o : order){
int count = o->second;
buckets[count-1].push_back(o->first);
}
std::vector<std::string> res;
for (auto it = buckets.rbegin(); it != buckets.rend(); ++it)
for (auto& str : *it)
res.push_back(str);