我目前正在学习加速C ++(Koenig / Moo)这本书,我在其中一个练习中遇到了麻烦。问题是编写一个程序,它将一些单词序列作为输入,然后将它存储在地图中。字符串是输入的单词,关联的int是每个单词出现的次数。然后,您必须按其出现的次数对单词进行排序;也就是说,通过价值而不是关键。您无法按值对地图进行排序,因此我尝试将元素复制到矢量中,我打算使用谓词进行排序。不幸的是,我得到的是一个充满g ++错误的屏幕。它们似乎来自同一个地方 - 将我的地图元素放入我的矢量中,我尝试这样做:
int main()
{
map<string, int> counters;
cout << "Enter some words followed by end-of-file (ctrl-d): ";
string word;
while (cin >> word)
++counters[word];
//maps cannot be sorted by values, so pass the elements of counters to a vector
vector<map<string, int> > vec_counters;
map<string, int>::const_iterator it = counters.begin();
while (it != counters.end()) {
vec_counters.push_back(*it);
++it;
}
这显然只是第一部分,但我甚至无法编译。我收到错误:
32:31:错误:没有匹配函数来调用std :: vector,int&gt; &gt; :: push_back(const std :: pair,int&gt;&amp;)' /usr/include/c++/4.5/bits/stl_vector.h:741:7:注意:候选者是:void std :: vector&lt; _Tp,_Alloc&gt; :: push_back(const value_type&amp;)[with _Tp = std :: map ,int&gt;,_ Alloc = std :: allocator,int&gt; &gt;,value_type = std :: map,int&gt;]
我想我做的事情从根本上说是愚蠢的...但我不能为我的生活看到什么......
任何帮助都会很棒!
C
答案 0 :(得分:4)
我很确定你不是在寻找地图矢量:
#include <map>
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<string, int> counters;
cout << "Enter some words followed by end-of-file (ctrl-d): ";
string word;
while (cin >> word)
++counters[word];
vector<std::pair<string, int> > vec(counters.begin(), counters.end());
}
答案 1 :(得分:2)
有点偏离主题,但这是一个使用bimap的性感解决方案,这是一个双方都作为键的地图。
#include <iostream>
#include <sstream>
#include <string>
#include <boost/bimap.hpp>
#include <boost/bimap/list_of.hpp>
#include <boost/bimap/set_of.hpp>
int main()
{
boost::bimap<boost::bimaps::set_of<std::string>, boost::bimaps::list_of<int>> m;
for (std::string line; std::getline(std::cin, line); )
{
++m.left[line];
}
auto & bml = m.left;
auto & bmr = m.right;
bmr.sort();
for (auto const & p : bml) { std::cout << p.first << " => " << p.second << "\n"; }
for (auto const & p : bmr) { std::cout << p.first << " => " << p.second << "\n"; }
}
答案 2 :(得分:0)
取消引用std::map<std::string, int>::const_iterator
会为您提供std::pair<std:string, int>
,而不是std::map<std::string, int>
,所以代替此:
vector<map<string, int> > vec_counters;
你想要这个:
vector<std::pair<string, int> > vec_counters;
答案 3 :(得分:0)
如果要在插入地图项后对向量进行排序,则也可以使用std::set
。集合中的元素总是被排序。如果您想在以后插入新元素,这将特别有用。但是,由于要按值对地图条目进行排序,因此必须将翻转的键值对存储到集合中。为了清楚起见,我省略了以下C ++ 11代码中的输入内容:
int main() {
std::map<std::string, int> counters{
{"sorted", 2}, {"value" , 5}, {"is" , 2}, {"by" , 3}, {"this" , 1}
};
std::set<std::pair<int, std::string>> s; // Use a set instead of a vector.
for (auto const &kv : counters)
s.emplace(kv.second, kv.first); // Flip the pairs.
for (auto const &vk : s)
std::cout << vk.second << ": " << vk.first << std::endl;
return 0;
}
输出:
此:1
是:2
排序:2
创建人:3
值:5
如果要按降序排序,则可以如下定义集合:
using flippedPair = std::pair<int, std::string>;
std::set<flippedPair, std::greater<flippedPair>> s;