0

I am working on an assignment where I have been given a large tab separated value txt file and I have to search through it using a good data structure. Now the problem I am facing is that I don't know if I am inserting the values correctly in this unordered_map with the key being a string and the values being a vector of struct. Secondly if I want to search how will it do it? For example if i enter the first ID how can i print out or access the other elements present in the struct?

Below is the sample data & code

id    effectiveTime    active    moduleId    definitionStatusId
100005    20020131    0    900000000000207008    900000000000074008
101009    20020131    1    900000000000207008    900000000000074008
102002    20020131    1    900000000000207008    900000000000074008
103007    20020131    1    900000000000207008    900000000000074008
104001    20020131    1    900000000000207008    900000000000073002
105000    20040731    0    900000000000207008    900000000000074008
106004    20020131    1    900000000000207008    900000000000074008
107008    20020131    1    900000000000207008    900000000000074008
108003    20020131    1    900000000000207008    900000000000074008
109006    20020131    1    900000000000207008    900000000000074008
110001    20020131    1    900000000000207008    900000000000074008
111002    20020131    1    900000000000207008    900000000000074008
112009    20020131    1    900000000000207008    900000000000074008
113004    20020131    1    900000000000207008    900000000000074008
114005    20020131    1    900000000000207008    900000000000074008
115006    20020131    1    900000000000207008    900000000000074008
116007    20020131    1    900000000000207008    900000000000074008
117003    20020131    1    900000000000207008    900000000000074008
118008    20020131    1    900000000000207008    900000000000074008
119000    20020731    1    900000000000207008    900000000000073002
120006    20020131    1    900000000000207008    900000000000074008
121005    20020131    1    900000000000207008    900000000000074008 

And here is the code

#include <iostream>
#include <vector>
#include <fstream>
#include <unordered_map>

using namespace std;

struct concept
{
    string id,effectiveTime,active,moduleId,definitionStatusId;
};

int main ()
{
    unordered_map<string,vector<concept>> concepts;
    ifstream conceptStream("concept.txt");
    if (!conceptStream.is_open())
    {
        cout << "Failed to open\n";
        return 0;
    }
    string id,effectiveTime,active,moduleId,definitionStatusId;
    string conceptLine;
    getline(conceptStream, conceptLine);
    while (!conceptStream.eof())
    {
        getline(conceptStream, id, '\t');
        getline(conceptStream, effectiveTime, '\t');
        getline(conceptStream, active, '\t');
        getline(conceptStream, moduleId, '\t');
        getline(conceptStream, definitionStatusId, '\n');
        concepts[id] = {{id,effectiveTime,active,moduleId,definitionStatusId}};
    }

  return 0;
}
affanmansoor
  • 15
  • 2
  • 8
  • What is your question exactly? If you want to access the value of a pair in the unordered_map, you simply do this: concepts[id].id etc. You used a hash structure, so the order of the data will not be preserved. You'll need to have other data structures to support both fast search and the order of the data, e.g. use a linked list to order all the data. – ozox Dec 10 '19 at 02:13
  • I am inserting the values here, concepts[id] = {{id,effectiveTime,active,moduleId,definitionStatusId}}; If i use the regular print method for unordered_maps, i can only print ->first and ->second i want to print these 5 values when ID is entered {{id,effectiveTime,active,moduleId,definitionStatusId}} – affanmansoor Dec 10 '19 at 02:16
  • If you can have multiple records with the same key, consider a `std::unordered_multimap`. If there are no duplicates, why are you storing a vector of concepts as the value type instead of just a concept? – Shawn Dec 10 '19 at 02:19
  • [Why is “while ( !feof (file) )” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – Shawn Dec 10 '19 at 02:20
  • The IDs are unique so i am setting them as the Key so there won't be any collisions, i just want the 1 key to store rest of the values so that when i search for the key it will bring all the other values in that row – affanmansoor Dec 10 '19 at 02:22
  • C++ version of @Shawn 's comment: [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) Added because while the problem is exactly the same, the cures are slightly different. – user4581301 Dec 10 '19 at 02:34
  • Sounds like there's no point to the vector then. – Shawn Dec 10 '19 at 02:53

1 Answers1

1

You search for a value by using find. You have a value if the iterator returned isn't equal to end().

unordered_map<string,vector<concept>>::const_iterator it = concepts.find(id);
if (it != concepts.end()) {} //You have a value

The vector you have inserted will always have one entry, so you could do away with that, but as you have it you need to get the first element of the vector.

if (it != concepts.end())
  cout << it->second[0].id << it->second[0].effectiveTime; //etc

Of course maybe you intend to see if the ID already exists and add it to the vector if it does. That will work, but maybe you should consider std::unordered_multimap as Shawn suggested, and if not, change the key type to concept as there will only ever be one element in the vector.

If you do remove the vector the access code becomes simpler:

if (it != concepts.end())
  cout << it->second.id << it->second.effectiveTime; //etc
Dominique McDonnell
  • 2,460
  • 14
  • 25