abhishek_naik
abhishek_naik

Reputation: 1297

Initialize my std::map

I have written the below code which uses a Map. This program finds the number of times the string key appears in the Map. If it appears only once, then the value of int for that string key should be 1, and so on. This program runs and produces the required output - but I feel that it is pure luck, because I am not initializing the Map anywhere. I am just doing myMap[str]++ - this in no way guarantees that initially the value was 0. So, how do I initialize the map so that the value for any string key is 0, before it is encountered and I do a myMap[str]++?

#include<cstdio>
#include<string>
#include<iostream>
#include<map>

int main()
{
    int t;
    long int n;
    std::string str;
    std::map< std::string, int > myMap;
    scanf("%d", &t);

    while(t--)
    {
        scanf("%ld", &n);
        std::cin.ignore();
        while(n--)
        {
            getline(std::cin, str);
            myMap[str]++;
        }

        for(std::map< std::string, int >::iterator it=myMap.begin(); it!=myMap.end(); it++)
            printf("%s %d\n", it->first.c_str(), it->second);
        printf("\n");

        myMap.erase(myMap.begin(), myMap.end());
    }

    return 0;
}

Sample input:

2
6
03 10103538 2222 1233 6160 0142
03 10103538 2222 1233 6160 0141
30 10103538 2222 1233 6160 0141
30 10103538 2222 1233 6160 0142
30 10103538 2222 1233 6160 0141
30 10103538 2222 1233 6160 0142

5
30 10103538 2222 1233 6160 0144
30 10103538 2222 1233 6160 0142
30 10103538 2222 1233 6160 0145
30 10103538 2222 1233 6160 0146
30 10103538 2222 1233 6160 0143

Sample output:

03 10103538 2222 1233 6160 0141 1
03 10103538 2222 1233 6160 0142 1
30 10103538 2222 1233 6160 0141 2
30 10103538 2222 1233 6160 0142 2

30 10103538 2222 1233 6160 0142 1
30 10103538 2222 1233 6160 0143 1
30 10103538 2222 1233 6160 0144 1
30 10103538 2222 1233 6160 0145 1
30 10103538 2222 1233 6160 0146 1

Detailed problem description can be found here.

Thanks!

Upvotes: 6

Views: 916

Answers (2)

BitTickler
BitTickler

Reputation: 11947

You can check if the key is already existing using std::map::find(). If it exists, you do the increment on the item pointed to by the iterator returned from find. Else, you write myMap[str] = 0.

   while(n--)
   {
        getline(std::cin, str);
        std::map< std::string, int >::iterator it = myMap.find(str);
        if( myMap.end() != it )
             (*it).second++;
        else
            myMap[str] = 1;
   }

Nevertheless, your code is okay as the the int is initialized in your code. It is just not visible (the std::pair<string,int> is being default-constructed).

Upvotes: 1

R Sahu
R Sahu

Reputation: 206717

You said:

this in no way guarantees that initially the value was 0

That is not correct. When an item corresponding to a key is not there in a map, it is value initialized when you use the operator[] function.

From http://en.cppreference.com/w/cpp/container/map/operator_at:

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.

In other words,

        myMap[str]++;

is valid and correct code.

Upvotes: 6

Related Questions