Link to home
Start Free TrialLog in
Avatar of girija_cv
girija_cv

asked on

how to get uniq records in c++

Hi,

I have one file, which looks as below,

 x.txt

abcd,123
abcd,1234
abcd,1235
abcd,1236
acd,131
acd,132
acd,133
abd,231
abd,232
abd,233

I need to print the unique name along with all its values. I have perl script I want to code it in c++
how to do it?

I need to print the o/p as follows.
eg.
abcd,123,1234,1235,1236
abd,231,232,233
acd,131,132,133

Perl code is as follows

while (<>)
{
        chop;
        ($loc,$xy) = split(/,/,$_);
        push @{$MY{$loc}},$xy;
}
foreach $loc (sort keys (%MY))
{
        #print $loc . "-" . join(" ",@{$MY{$loc}}) . "\n" if ($loc);
        print "$loc,@{$MY{$loc}}\n" if ($loc);
}


c++ coding is as follows but it is not working properly.Can any one solve this problem?


#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <list>
using namespace std;

 struct CityParms {
        std::string loc,poco;
        std::list<std::string> xy_list;
            CityParms(const std::string& poco = "",const std::string& loc = "") : poco(poco),loc(loc){}
};
typedef std::map<std::string,CityParms> CityParmsMap;

void process_a(CityParmsMap& map);
void report(const CityParmsMap& map);


int main()
{
        CityParmsMap map;
        process_a(map);
            report(map);

}

void process_a(CityParmsMap& map)
{
        std::ifstream f("x.txt");
        std::string str;
        while (!f.eof())
            {
                        getline(f,str);
                std::istringstream istr(str);
                std::string str,poco,loc;
                getline(istr,loc,',');
                        getline(istr,poco,',');
                        
                        cout << loc << '#' << poco << endl;
                map[loc] = CityParms(poco);
                        CityParmsMap::const_iterator Citr = map.find(loc);
                                    if(Citr != map.end())
                                    {
                                    CityParms& cityParms = map[loc];
                                    cityParms.loc = loc;
                        cityParms.xy_list.push_back(poco);
                                    }
                        
            }
}

void report(const CityParmsMap& map)
{
        std::ofstream fo("push_out.dat");
        typedef CityParmsMap::const_iterator Citr;
        for (Citr itr = map.begin();itr != map.end();++itr) {
               
                const CityParms& cityParms = itr->second;
                typedef std::list<std::string>::const_iterator Citr;
                const std::list<std::string> &xy_list = cityParms.xy_list;
                        
                        if (!xy_list.size())
                              continue;
                               fo << cityParms.loc << ',';
                               copy (xy_list.begin(),xy_list.end(),std::ostream_iterator<std::string>(fo));
                              
               
             
        }
}

Avatar of stefan73
stefan73
Flag of Germany image

Hi girija_cv,
> typedef std::map<std::string,CityParms> CityParmsMap;

Use a simpler approach:

typedef std::map<std::string,vector<std::string> > CityParmsMap;

Then you'll have a very similar behaviour as your Perl script.


Cheers,
Stefan
Try this:

    map<string, list<int>* >  cmap;

    ifstream ifs("x.txt");
    string line, key;
    int    num;

    map<string, list<int>* >::iterator itr;

    while (!ifs.eof())
    {
        getline(ifs, line);
       
        if (line.empty())
            break;
        istringstream iss1(line);
        getline(iss1, key, ',');
        iss1 >> num;  
       
       
        if ((itr = cmap.find(key)) == cmap.end())
        {
            list<int>* plist = new list<int>;
            plist->push_back(num);
            cmap[key] = plist;
        }
        else
        {
            list<int>*& plist = cmap[key];
            plist->push_back(num);
        }
   }

   for (itr = cmap.begin(); itr != cmap.end(); ++itr)
   {
       pair< string, list<int>* > pr = *itr;
       key  = pr.first;
       list<int>* pl = pr.second;
       
       cout << key ;  
       list<int>::iterator it;
       for (it = pl->begin(); it != pl->end(); ++it)
           cout << "," << *it;
       cout << endl;
   }

   ifs.close();


Regards, Alex
if you want to sort them add sort() function when outputting the results

       list<int>* pl = pr.second;
       pl->sort();

Regards, Alex
 
ASKER CERTIFIED SOLUTION
Avatar of rstaveley
rstaveley
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
[Shouldn't have posted really, but having done all of that typing, I couldn't bear the thought of leaving it.]
>>whatever project that they are supposed to be working on in the real world too

project?? real world?? what are you talking about?

- sardonic grin - ;-)

Regards, Alex