我试图让所有的相同的字符串的数量在矢量输出作为一个更大的计划的一部分。 大量的研究后,我设法把东西在一起工作,但它似乎乱,我想知道是否有更好的方式来做到这一点。
#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个额外的功能,使工作或不得不作出的全球地图是敏锐的。 任何提示将受到欢迎。
Answer 1:
那么最简单的方法没有多余的功能,而不必在地图全球将不使用的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]=0;
for (vector<string>::iterator i = myVector.begin(); i != myVector.end(); ++i)
++myMap[*i];
一旦你做了,你也可以删除第一个循环
map<string, int> myMap;
for (vector<string>::iterator i = myVector.begin(); i != myVector.end(); ++i)
++myMap[*i];
因为地图值将被初始化反正到零。
是什么让你认为你反正用的for_each?
Answer 2:
你setMap
功能是不必要的。
考虑这个函数做什么,应地图的关键不存在。
void addMap(string i)
{
myMap[i]++;
}
表达myMap[i]
将添加一个新的关键是你的地图。
由于值类型是int
,这个新值将是int()
其被保证是0
。
Answer 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;
简单的演示
Answer 4:
在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]
会自动插入s
成m
,如果不是已经存在。
使用std::unordered_map
(哈希表)可能会比便宜std::map
(平衡树)。
你可以做除“每个”上面显示的循环将通过常规的“for”循环替换下C ++ 03非常类似的东西。
Answer 5:
#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
文章来源: Easier way to count identical strings in a vector?