I have one std::vector<MyString>
which data is not unique. Actually, most strings are repeated. And I have to find the unique ones and their repeat number.
I use map:
std::map<MyString,unsigned short> stringsMap;
.......
if ( stringsMap.find( currentString ) == stringsMap.end() )
{
stringsMap[ currentString ] = 0;
}
stringsMap[ currentString ]++;
........
Do you have ideas how it could be done on fewer lines?
It could be done on one row: stringsMap[ currentString ]++;
however short has indeterminate value by default.
It could be done on one row: stringsMap[ currentString ]++; however short has indeterminate value by default.
This is not true, value is well defined as stated in documentation :
If an insertion is performed, the mapped value is value-initialized (default-constructed for class types, zero-initialized otherwise ) and a reference to it is returned.
emphasis is mine.
So it is perfectly fine to write one liner:
stringsMap[ currentString ]++;
and this is common practice and even given as an example in the documentation:
// count the number of occurrences of each word
// (the first call to operator[] initialized the counter with zero)
std::map<std::string, size_t> word_map;
for (const auto &w : { "this", "sentence", "is", "not", "a", "sentence",
"this", "sentence", "is", "a", "hoax"}) {
++word_map[w];
}
however short has indeterminate value by default.
No. For a non existing key the map will use T()
to initialize the value of the newly created entry, which effectively evaluates to 0
for unsigned short
.
See the std::map::operator[]
documentation (emphasis mine 1 ):
1) Inserts
value_type(key, T())
if the key does not exist. This function is equivalent toreturn insert(std::make_pair(key, T())).first->second;
-key_type
must meet the requirements ofCopyConstructible
.
-mapped_type
must meet the requirements ofCopyConstructible
andDefaultConstructible
.
If an insertion is performed, the mapped value is value-initialized (default-constructed for class types, zero-initialized otherwise ) and a reference to it is returned.
Thus, writing just
std::map<MyString,unsigned short> stringsMap;
.......
stringsMap[ currentString ]++;
is perfectly fine. The entire if
block is redundant and not needed.
1) That's not really true, it was @Remy Lebau 's emphasis
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.