C ++: push_back картав вектор> через итератор? - PullRequest
4 голосов
/ 25 января 2012

Я сейчас изучаю книгу ускоренного C ++ (Кениг / Му) и у меня возникли проблемы с одним из упражнений.Проблема состоит в том, чтобы написать программу, которая принимает в качестве входных данных некоторую последовательность слов, которую затем сохраняет на карте.Строки - это введенные слова, а связанное с ними 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>> :: push_back (const std :: pair, int> &) '/ usr / include/c++/4.5/bits/stl_vector.h:741:7: примечание: кандидат: void std :: vector <_Tp, _Alloc> :: push_back (const value_type &) [with _Tp = std :: map, int>, _Alloc= std :: allocator, int>>, value_type = std :: map, int>]

Полагаю, я делаю что-то принципиально глупое ... но я не могу за всю жизнь понять, что..

Любая помощь будет отличной!

C

Ответы [ 4 ]

4 голосов
/ 25 января 2012

Я почти уверен, что вы не ищете вектор карт:

#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());
}
2 голосов
/ 25 января 2012

Немного не по теме, но вот сексуальное решение с использованием 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"; }
}
1 голос
/ 25 января 2012

Вы хотите поместить элементы карты в вектор.Карты составлены из пар, а не из других карт.Следовательно, ваш вектор должен быть вектором пар.

Тем не менее, похоже, что причина, по которой вы хотите, чтобы вектор был в первую очередь, заключается в сортировке по значениям на карте.Почему бы тогда не сделать карту map< int, string >?Это приведет к тому, что он будет отсортирован по возрастанию по целым числам: элементы на карте отсортированы по значению ключа от нижнего к верхнему в соответствии с определенным критерием строгого слабого упорядочения.

0 голосов
/ 25 января 2012

Разыменование 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;
...