Rndp13
Rndp13

Reputation: 1122

STL map to find the first non repeatable character

I have written a small C++ program to keep a count of the alphabets. I am using stl map for the same,

Interestingly, i am not getting the list as it appeared in the input. For example for the word TESTER, my program should give

T  2
E  2
S  1
R  1

But its giving,

E       2
R       1
S       1
T       2

change in the position of the alphabets,

I want the o/p of the alphabets as it appeared in the input. Please help me if i am missing anything.Here is my code

#include<iostream>
#include<map>

using namespace std;

int main()
{
    char *str = "TESTER";
    map<char,int> checkmap;
    map<char,int>::iterator p;
    int i;
    while( *str != '\0' )
    {
        p = checkmap.find(*str);
        i = p->second;
        if(p == checkmap.end())
        {
            checkmap.insert(std::make_pair(*str,++i));
        }
        else
        {
            p->second = ++(p->second);
        }
    str++;
    }
    for(p=checkmap.begin(); p!=checkmap.end(); p++)
    {
        /*if(p->second == 1)
        {
            cout<<(*p).first<<endl;
        }*/
        cout<<p->first<<"\t"<<p->second<<endl;
    }

    return 0;
}

Upvotes: 2

Views: 106

Answers (3)

Vlad from Moscow
Vlad from Moscow

Reputation: 311058

Here is shown an approach how it can be done

#include <iostream>
#include <map>
#include <cstring>

int main() 
{
    const char *str = "TESTER";

    auto order = [&]( char c1, char c2 )
    {
        return ( std::strchr( str, c1 ) < std::strchr( str, c2 ) );
    };

    std::map<char, int, decltype( order )> m( order );

    for ( const char *p = str; *p; ++p ) ++m[*p];

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

    return 0;
}

The program output is

T 2
E 2
S 1
R 1

Upvotes: 5

bhavesh
bhavesh

Reputation: 1406

There is no way to keep track of the order in which elements are added to map. To get the same order it would be advisable to use std::vector<std::char, int> and then update the same.

Upvotes: 0

juanchopanza
juanchopanza

Reputation: 227468

You're missing that std::map has its own internal ordering, which is completely independent of the order in which elements are added. As you can see from your example, it is ordered alphabetically. This is in increasing order of the value of the char key.

Also note that your map manipulations are overly complex. All you need to do is

char *str = "TESTER";
map<char,int> checkmap;

while( *str != '\0' )
{
    checkmap[*str]++;
    ++str;
}

The while can be collapsed further if you're into that kind of thing:

while( *str != '\0' ) checkmap[*str++]++;

For the general problem of mapping values while maintaining insertion order, see A std::map that keep track of the order of insertion?

Upvotes: 1

Related Questions