如何解决如何在 C++ 中订购具有重复值的地图?
我试图根据值以降序方式对地图重新排序,我一直在尝试创建一个新地图并首先插入具有最大价值的地图,但它一直按键对地图进行排序。>
我还尝试通过将地图形式更改为另一种方式的值对其重新排序,但我会丢失一些数据,因为我有多个具有相同值的键。
#include <iostream>
#include "SymbolFreq.h"
#include <string>
#include <fstream>
#include <streambuf>
#include <map>
using namespace std;
int main()
{
map <char,int> mymap;
map <char,int> realmap;
ifstream infile{ "ToCompress.txt" };
std::string str((std::istreambuf_iterator<char>(infile)),std::istreambuf_iterator<char>());
std::map<char,int>::iterator itera;
for (auto it = str.begin(); it != str.end(); ++it)
{
itera = mymap.find(*it);
if (itera != mymap.end())
{
itera->second++;
}
else
{
mymap.insert({ *it,1 });
}
}
int max = 0;
char provisionalChar;
int provisionalInt;
while (mymap.empty() == false)
{
for (auto it = mymap.cbegin(); it != mymap.cend(); ++it)
{
if (it->second > max)
{
max = it->second;
provisionalChar = it->first;
provisionalInt = it->second;
}
//cout << it->first << "\t" << it->second << "\n";
}
mymap.erase(provisionalChar);
realmap.insert({ provisionalChar,provisionalInt });
max = 0;
}
for (auto it = realmap.cbegin(); it != realmap.cend(); ++it)
{
cout << it->first << "\t" << it->second << "\n";
}
return 0;
}
解决方法
如果我正确理解了这个问题,您想计算每个 char
在文件中出现的次数,然后生成一个地图,按照出现次数最多的 char
进行排序。>
这是一个想法:
#include <algorithm>
#include <cstdint>
#include <fstream>
#include <functional>
#include <iostream>
#include <iterator>
#include <map>
#include <string>
#include <unordered_map>
int main() {
std::ifstream infile{"ToCompress.txt"};
// "mymap" is only used for counting how many times each char appears.
std::unordered_map<char,std::uintmax_t> mymap;
// Loop directly over the file. No vector needed:
std::for_each(std::istreambuf_iterator<char>(infile),std::istreambuf_iterator<char>(),[&mymap](char ch) {
// No need to find first - operator[] inserts an element
// for the key ("ch") if it's missing.
++mymap[ch];
});
// Transform the unordered_map into a multimap where the count is the key
// and in which we use a descending sort order (std::greater):
std::multimap<std::uintmax_t,char,std::greater<std::uintmax_t>> realmap;
std::transform(mymap.begin(),mymap.end(),std::inserter(realmap,realmap.end()),[](const auto& ch_co) -> std::pair<std::uintmax_t,char> {
// return a pair with key and value swapped
return {ch_co.second,ch_co.first};
});
// Print the result
for(auto& [count,ch] : realmap) {
std::cout << count << '\t' << ch << '\n';
}
}
可能的输出:
537479
120204 t
113285 e
80681
80670 i
79862 n
77984 r
77464 s
69994 o
67377 a
...
显然,<space>
、t
、e
和 \n
是我的 C++ 程序中最常见的字符(这是我用作输入的字符)
您的问题可能不恰当;退后一步,说明你真正想要实现的目标。
也就是说,我会根据您所写的内容尝试回答。
看起来您正在尝试按值对 std::map 进行排序,在这种情况下,您的问题与 this 或 this 问题重复。
关于您最初的尝试:
看看this table。只有序列容器允许您直接影响顺序。与优先队列一样,您对关联容器的顺序的控制有限,对无序容器的控制几乎为零。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。