2013-04-18 48 views
1

我想獲得一個向量中的所有相同字符串的數量輸出作爲一個更大的程序的一部分。經過大量研究後,我設法將一些東西放在一起,但似乎很雜亂,我想知道是否有更好的方法來做到這一點。更容易的方法來計算矢量中的相同字符串?

#include <vector> 
#include <string> 
#include <map> 
#include <algorithm> 
#include <iostream> 

using namespace std; 

void setMap(string i); 
void addMap(string i); 
map<string, int> myMap; 

int main() 
{ 
    vector<string> myVector; 
    string myArray[6]={"foo","foo","bar","roo","foo","bar"}; 
    for (int i=0; i<6; i++) 
    { 
     myVector.push_back(myArray[i]); 
    } 
    for_each (myVector.begin(), myVector.end(), setMap); 
    for_each (myVector.begin(), myVector.end(), addMap); 
    for (map<string, int, less<string>>::const_iterator iter = myMap.begin(); 
     iter != myMap.end(); ++iter) 
     cout <<iter->first<<'\t'<<iter->second<<endl; 
    return 0; 
} 

void setMap(string i) 
{ 
    myMap[i]=0; 
} 

void addMap(string i) 
{ 
    myMap[i]++; 
} 

此代碼工作正常,給我輸出我之後,但我不是不必增加2個額外的功能,使工作或不得不作出的全球地圖是敏銳的。任何提示都會受到感謝。

+0

C++ 03或C++ 11? – leemes

+0

如果你想使用'for_each',你可以使用* functor *來設計你的地圖引用,從而消除你的代碼塊。 [看到它](http://ideone.com/ZbMU8r)。使用* lambda *可以使*更緊湊。 [也看到它](http://ideone.com/H59HHM)。 – WhozCraig

回答

4

那麼最簡單的方法不具有額外的功能,並沒有地圖作爲全球將不使用for_each。

for_each (myVector.begin(), myVector.end(), setMap); 
for_each (myVector.begin(), myVector.end(), addMap); 

成爲

​​

一旦你做了,你也可以去掉第一循環

map<string, int> myMap; 
for (vector<string>::iterator i = myVector.begin(); i != myVector.end(); ++i) 
    ++myMap[*i]; 

因爲地圖值無論如何都會被初始化爲零。

是什麼讓你覺得你不得不使用for_each?

+0

對C++來說很新,實際上是編程。這對我來說似乎是有道理的,因爲我沒有那麼多的矢量經驗,以前從未使用過地圖。我正在進行的項目是一個巨大的學習曲線,這個網站幫了我很多。 – Modred

+0

for_each只是for循環恕我直言的一個更尷尬的版本,我幾乎從未發現自己寫了一個。 – john

+0

作品完美(除了a,其中a;應該是,但我們都會犯錯字)。不能要求更好的解決方案。 – Modred

3

這個怎麼樣?將計數機制封裝在單獨的函數中以實現可重用性。

// Iterator pair based interface 
template <class Iterator> 
std::map<typename Iterator::value_type,int> 
count(Iterator begin, Iterator end) { 
    std::map<typename Iterator::value_type,int> counts; 
    for (Iterator i = begin; i != end; ++i) 
     counts[*i]++; 
    return counts; 
} 

// Sequence interface 
template <class Sequence> 
inline std::map<typename Sequence::value_type,int> 
count(Sequence seq) { 
    return count(seq.begin(), seq.end()); 
} 

然後簡單地使用這樣的:

// C++11 
for (const auto & c : count(myVector)) 
    cout << c->first << '\t' << c->second << endl; 

// C++03 
std::map<string,int> counts = count(myVector); 
for (std::map<string,int>::const_iterator c = counts.begin(), e = counts.end(); c != e; ++c) 
    cout << c->first << '\t' << c->second << endl; 

Simple demo

+0

你需要'template std :: map count(Sequence seq){return count (seq.begin(),seq.end()) ;}'。 –

+0

剛剛看到默認的模板參數也是C++ 11。該死的,我太習慣了;) – leemes

+0

好的,現在修復了。 – leemes

3

setMap功能是不必要的。

請考慮這個函數做了什麼,如果地圖的鍵不存在。

void addMap(string i) 
{ 
    myMap[i]++; 
} 

表達myMap[i]將添加一個新的關鍵是你的地圖。

由於值類型爲int,因此此新值將爲int(),該值保證爲0

2

在C++ 11,你可以這樣做:

#include <string> 
#include <unordered_map> 
#include <iostream> 

int main() { 

    std::string myArray[6] = {"foo","foo","bar","roo","foo","bar"}; 

    std::unordered_map<std::string, size_t> m; 
    for (const auto& s : myArray) 
     ++m[s]; 

    for (const auto& p : m) 
     std::cout << p.first << "\t" << p.second << std::endl; 

} 

此打印:

foo  3 
bar  2 
roo  1 

這工作,因爲m[s]會自動如果不是已經有插入sm

使用std::unordered_map(散列表)可能會比std::map(平衡樹)便宜。


你可以做除「每個」上面顯示的循環將通過常規的「for」循環替換下C++ 03非常類似的東西。

0
#include <iostream> 
#include <string> 
#include <vector> 
#include <iterator> 
#include <map> 

using namespace std; 

int main (int argc, char * const argv[]) { 

    string myArray[]={"foo","foo","bar","roo","foo","bar"}; 
    int arr_length = 6; 
    vector<string> myVector(myArray, myArray + arr_length); 

    //Print contents of vector: 
    copy(myVector.begin(), 
     myVector.end(), 
     ostream_iterator<string>(cout, " ") 
    ); 

    cout << endl; 



    map<string, int> myMap; 

    vector<string>::iterator pos; 
    for (pos=myVector.begin(); pos<myVector.end(); ++pos) 
    { 
     myMap[*pos] += 1; 
    } 

    map<string, int>::iterator mapPos; 
    for (mapPos=myMap.begin(); mapPos != myMap.end(); ++mapPos) { 
     cout << "word: " << mapPos->first << "\t" 
      << "count: " << mapPos->second << endl; 
    } 




     return 0; 
} 


--output:-- 
foo foo bar roo foo bar 
word: bar count: 2 
word: foo count: 3 
word: roo count: 1 
相關問題