1

该程序将配对存储在地图中,计算单词出现的次数。目标是让数据按出现次数排序并以值/字符串形式输出。显然,法线贴图是按字符串键排序的,所以我不得不反转它。

为此,我阅读文字,并在地图中适当地增加它们的值。然后我创建了一个多图并将地图对复制到多图中,但相反。然后我遍历多图,输出对。但是,当我尝试输出这些对时会发生运行时错误,但我不确定为什么。

这是代码:

#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';
}

任何帮助表示赞赏。

PS我在不同的地方读到multimap可以在一个键中多次出现一个键(这就是我首先使用它的原因)和/或多个值。关于哪个是真的或者两者是否都是真的,一些澄清会很好。

还有任何类型的地图复制算法吗?为简单起见,我决定只使用 for 循环,编写自定义副本可能相当容易,但我只是想知道(用于将映射复制到其他配对容器并复制到输出。)

4

3 回答 3

2
 for (p2 = words2.begin(); p2!=words2.end(); ++p2)
        cout << p->first << ": " << p->second << '\n';

输出语句中的 p 不应该是 p2 吗?

于 2009-08-30T16:28:23.520 回答
1

打印时您似乎使用 p 而不是 p2 ,将输出行更改为:

cout << p2->first << ": " << p2->second << '\n';

如果您在 for 循环中而不是在它之前声明 p,则可以避免此错误,因为它会在第一个 for 循环结束后超出范围。

于 2009-08-30T16:29:00.307 回答
0

我知道这是从 2009 年开始的,但要回答问题的第二部分,是的,有一些算法std可以在范围之间复制元素。在具有相同值类型的容器之间复制时,使用std::copywithstd::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::copystd::transform等... 几乎可以与来自 的任何容器一起使用std。这不是特定于std::map. 您还可以使用std::front_inserterstd::back_inserter具有push_front()相应的容器。push_back()方法。

于 2015-03-02T06:34:00.903 回答