Вывод мультикарты после копирования с карты

StackOverflow https://stackoverflow.com/questions/1354224

  •  20-09-2019
  •  | 
  •  

Вопрос

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

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

Вот этот код:

#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 для простоты, и, вероятно, было бы довольно легко написать пользовательскую копию, но мне просто интересно (для копирования карт в другие парные контейнеры и копирования в output).

Это было полезно?

Решение

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

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

Другие советы

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

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

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

Я знаю, что это с 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() методы.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top