Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Howto Create Map of Vector From Sorted Data

I have the following data as input (sorted by first column):

foo 1 2
foo 3 3
bar 10 11

I want to create a Map of Vector with first column as key of the map such that we have:

foo = {1,2,3,3}
bar = {10,11}

But why my code below doesn't work as expected?

    #include <vector>
    #include <map>
    #include <iostream>
    #include <fstream>
    #include <sstream>

    using namespace std;

    int main  ( int arg_count, char *arg_vec[] ) {
        if (arg_count !=2 ) {
            cerr << "expected one argument" << endl;
            return EXIT_FAILURE;      
        }

        string line;         
        ifstream acemblyfile (arg_vec[1]); 

        map <string, vector<int> > myMapOfVec; 
        vector <string> myVec;  
        string KEY = "" ;    


        if (acemblyfile.is_open())
        {
            while (getline(acemblyfile,line) )
            {
                stringstream ss(line);    
                string KEY_TEMP;
                int VAL1;
                int VAL2;           

                ss >> KEY_TEMP >> VAL1 >> VAL2;

                MyVec.push_back(VAL1);   
                MyVec.push_back(VAL2);   


                if (KEY_TEMP != KEY) {     
                  myMapOfVec[KEY] = MyVec;
                  KEY = KEY_TEMP;            
                  MyVec.clear();          
                }

            }
            acemblyfile.close();      
        }
        else {
            cout << "Unable to open file"; 
        }


for( map<string, vector<int> >::iterator iter = myMapOfVec.begin(); iter != myMapOfVec.end(); ++iter ) {
       vector <int> tempVec = (*iter).second;
       string Key = (*iter).first;
       for (unsigned i =0; i<tempVec.size(); i++) {
          cout << Key << " " << tempVec[i] << endl;
       }
    }

        return 0;
    }
like image 215
neversaint Avatar asked Mar 16 '09 09:03

neversaint


People also ask

Does map store in sorted order?

Maps are associative containers that store elements in a mapped fashion. Each element has a key value and a mapped value. No two mapped values can have equal key values. By default, a Map in C++ is sorted in increasing order based on its key.

Is std::map sorted?

std::map is a sorted associative container that contains key-value pairs with unique keys. Keys are sorted by using the comparison function Compare . Search, removal, and insertion operations have logarithmic complexity. Maps are usually implemented as red-black trees.

Can we make vector of map?

Vector elements are placed in contiguous storage so that they can be accessed and traversed using iterators. Vector of Maps in STL: Vector of maps can be used to design complex and efficient data structures.

Can map be sorted by value?

We can sort the entries in a HashMap according to keys as well as values. In this tutorial we will sort the HashMap according to value. The basic strategy is to get the values from the HashMap in a list and sort the list. Here if the data type of Value is String, then we sort the list using a comparator.


2 Answers

As Mykola said, you should use the vector in the map instead of creating one yourself. I changed your whole code so it works for me. Note that you wrote some of the variable names with wrong case (MyMapOfVec instead of myMapOfVec) and this led to compiler errors.

Also be sure you don't have a newline at the end of your input file because this will result in repeating the last line.

#include <vector>
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

int main  ( int arg_count, char *arg_vec[] ) {
    if (arg_count !=2 ) {
        cerr << "expected one argument" << endl;
        return EXIT_FAILURE;      
    }

    string line;         
    ifstream acemblyfile (arg_vec[1]); 

    map <string, vector<int> > myMapOfVec; 
    string KEY;    


    if (acemblyfile.is_open())
    {
        while (getline(acemblyfile, line) )
        {
            stringstream ss(line);    
            int VAL1;
            int VAL2;

            ss >> KEY >> VAL1 >> VAL2;

            myMapOfVec[KEY].push_back(VAL1);
            myMapOfVec[KEY].push_back(VAL2);

        }
        acemblyfile.close();      
    }
    else {
        cout << "Unable to open file"; 
    }


for( map<string, vector<int> >::iterator iter = myMapOfVec.begin(); iter != myMapOfVec.end(); ++iter ) {
   vector<int> tempVec = (*iter).second;
   string Key = (*iter).first;
   cout << Key;
   for (unsigned i = 0; i < tempVec.size(); i++) {
      cout << " " << tempVec[i];
   }
   cout << endl;
}

    return 0;
}

For your example, this gives the output

bar 10 11
foo 1 2 3 3
like image 168
schnaader Avatar answered Oct 22 '22 17:10

schnaader


Don't add check for KEY_TEMP != KEY. Because in your case they are equal as foo goes two times one by one. Just

myMapOfVec[KEY].push_back( VAL1 );
myMapOfVec[KEY].push_back( VAL2 );
like image 38
Mykola Golubyev Avatar answered Oct 22 '22 15:10

Mykola Golubyev