该程序将对存储在地图中,计算单词出现的次数。目标是使数据按出现次数排序,并以值/字符串形式输出。显然,法线贴图按字符串键排序,所以我不得不反转它。
要做到这一点,我会用文字阅读,并在地图中适当增加它们的值。然后我创建一个多图并将地图中的对复制到多图中,但是相反。然后我遍历多图,输出对。但是,当我尝试输出对时发生运行时错误,我不知道为什么。
以下是代码:
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<string, int> words;
multimap<int, string> words2;
string s;
while (true) {
cin >> s;
if (s == "0") break;
++words[s];
}
map<string, int>::iterator p;
for (p = words.begin(); p!=words.end(); ++p)
words2.insert(make_pair(p->second, p->first));
multimap<int, string>::iterator p2;
for (p2 = words2.begin(); p2!=words2.end(); ++p2)
cout << p->first << ": " << p->second << '\n';
}
感谢任何帮助。
P.S。我在不同的地方读到,multimap可以有多个密钥出现(这就是我首先使用它的原因)和/或单个密钥中的多个值。关于哪个是真的或者两者都是真的,一些澄清会很好。
地图也有任何类型的复制算法吗?为了简单起见,我决定只使用for循环,编写自定义副本可能相当容易,但我只是想知道(将映射复制到其他对容器并复制到输出。)
答案 0 :(得分:2)
for (p2 = words2.begin(); p2!=words2.end(); ++p2)
cout << p->first << ": " << p->second << '\n';
输出语句中的p不应该是p2的吗?
答案 1 :(得分:1)
打印时似乎使用p而不是p2,将输出行更改为:
cout << p2->first << ": " << p2->second << '\n';
如果在for循环中而不是在for循环中声明了p,则会避免此错误,因为在第一个for循环结束后它将超出范围。
答案 2 :(得分:0)
我知道这是从2009年开始的,但要回答问题的第二部分,是的std
中有算法来复制范围之间的元素。在具有相同值类型的容器之间进行复制时,使用带有std::copy
的{{1}}将执行:
std::inserter
由于您要复制到不同类型的容器,因此在将元素插入第二个容器之前,可以使用map<string, int> wordsA;
multimap<string, int> wordsB;
copy(wordsA.begin(), words.end(), inserter(wordsB, wordsB.begin()));
将转换函数应用于元素:
std::transform
通常情况下,这实际上最终会比您的简单循环更多的代码行并且基本上相同:)
请注意,transform(words.begin(), words.end(),
std::inserter(words2, words2.begin()),
[](const pair<string, int>& x) -> pair<int, string>
{
return make_pair(x.second, x.first);
}
);
,std::copy
等...将适用于来自std::transform
的几乎任何容器。这不是std
特有的。您还可以将std::map
和std::front_inserter
与容器std::back_inserter
一起使用。 push_front()
方法。