2012-01-24 57 views
4

我目前正在學習加速C++(Koenig/Moo)這本書,並且遇到了其中一個練習題。問題在於編寫一個程序,該程序將輸入的一系列單詞作爲輸入,然後將其存儲在地圖中。字符串是輸入的單詞,關聯的int是每個單詞出現的次數。然後,您必須按照它們出現的次數對單詞進行排序;也就是說,是由價值而不是關鍵。您無法通過值對地圖進行排序,因此我試圖將元素複製到矢量中,而不是使用謂詞進行排序。不幸的是,我所得到的只是一個充滿g ++錯誤的屏幕。他們似乎是從同一個地方幹 - 把我的地圖元素融入我的載體,我試着這樣做:C++:通過迭代器將地圖<string, int> push_back成一個vector <map <string, int>>?

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:note:candidate is:void std :: vector < _Tp,_Alloc> :: push_back(const value_type &)[with _Tp = std :: map,int>,_Alloc = std :: allocator,int>>,value_type = std :: map,int>]

我想我正在做一些根本上愚蠢的事情......但我不能爲我的生活看到什麼..

任何幫助將是偉大的!

Ç

+1

這聽起來像是Boost.Bimap的工作! –

回答

3

我敢肯定你不尋找地圖的矢量:

#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()); 
} 
+0

Arr,部分'std'施虐者! –

+0

@KerrekSB:不是。我剛剛從OP中複製了樣本,並且我無法打破我的良好習慣:)(_hi,順便說一句) – sehe

+0

謝謝sehe,我的一個愚蠢的錯誤 - 顯然只有一張地圖。不過,我不知道地圖的每個元素都被稱爲一對。 KarrekSB:你在實際的代碼中提到了std ::的部分使用。我傾向於將所有'使用std :: cin;'在開始時輸入行。這被認爲是不好的做法? – weatherwax007

0

解引用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; 
+0

這個問題可能是有史以來最晦澀難懂的C++ STL使用問題之一。跟進OP的問題,'std :: pair'是否仍然可以爲您提供'std :: map'快速檢索的好處? –

+0

@XavierHo:'std :: pair '有一個'std :: string'和一個'int',所以它實際上比'std :: map'快得多,具有可能具有多個元素的所有開銷。 – ruakh

+0

重讀OP的問題後,我想我誤解了他的意圖。是的,'std :: pair'將是用例的最佳選擇。我在考慮實際上在'std :: vector'中有一個'std :: map',這是一個完全不同的數據結構。 –

1

您想將地圖的元素放入矢量中。地圖是由成對出來的,而不是其他地圖。因此,你的向量應該是一個對的向量。

這就是說,它看起來像你想要矢量首先的原因是按照地圖中的值進行排序。那麼爲什麼不製作地圖map< int, string >呢?這將導致按ints升序排序:映射中的元素按照特定的嚴格弱排序標準從低到高的鍵值進行排序。

2

有點偏離主題,但這裏是一個性感的解決方案,使用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"; } 
} 
+0

謝謝!甚至沒有意識到bimap。 – weatherwax007

相關問題