Многокарточный вывод после копирования с карты - PullRequest
1 голос
/ 30 августа 2009

Эта программа хранит пары на карте, считая количество встречений слова. Цель состоит в том, чтобы отсортировать данные по количеству вхождений и вывести их в виде значения / строки. Очевидно, что карта нормалей сортируется по строковому ключу, поэтому мне пришлось повернуть ее вспять.

Для этого я читаю словами и соответствующим образом увеличиваю их значения на карте. Затем я создаю мультикарту и копирую пары с карты в мультикарту, но в обратном порядке. Затем я перебираю мультикарту, выводя пары. Тем не менее возникает ошибка во время выполнения, когда я пытаюсь вывести пары, и я не уверен, почему.

Вот код:

#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. Я читал в разных местах, что у нескольких карт может быть несколько вхождений ключа (именно поэтому я использовал его в первую очередь) и / или несколько значений в одном ключе. Было бы неплохо дать некоторые разъяснения относительно того, что является правдой или являются ли оба фактами истинными.

Также существует ли какой-либо алгоритм копирования для карт? Я решил просто использовать цикл for для простоты, и, вероятно, было бы довольно легко написать пользовательскую копию, но мне просто интересно (для копирования карт в другие контейнеры пары и копирования на выход.)

Ответы [ 3 ]

2 голосов
/ 30 августа 2009
 for (p2 = words2.begin(); p2!=words2.end(); ++p2)
        cout << p->first << ": " << p->second << '\n';

Разве не должны быть p в вашем выходном операторе p2?

1 голос
/ 30 августа 2009

При печати вы используете p, а не p2. Измените строку вывода на:

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

Этой ошибки можно было бы избежать, если бы вы объявили p в цикле for, а не до него, поскольку она вышла бы из области действия после завершения первого цикла for.

0 голосов
/ 02 марта 2015

Я знаю, что это с 2009 года, но, чтобы ответить на вторую часть вопроса, да, в std есть алгоритмы для копирования элементов между диапазонами. При копировании между контейнерами с одним и тем же типом значения использование std::copy с 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() соотв. push_back() методов.

...