Map with struct as key and vector as value


 
Thread Tools Search this Thread
Top Forums Programming Map with struct as key and vector as value
# 1  
Old 09-15-2014
Map with struct as key and vector as value

Hello,
Trying to challenge myself with C++ STL.
I want to read in data from file and do some calculation, adapted from an exercise of a book (C++ for engineers and scientist, 3rd Ed, Gary Bronson).
infile is like:
Code:
ID Name Course Credit Grade
2333021 Bokow,R. NS201 3 A
2333021 Bokow,R. MG342 3 A
2333021 Bokow,R. FA302 1 A
2574063 Failin,D. MK106 3 C
2574063 Failin,D. MA208 3 B
2574063 Failin,D. CM201 3 C
2574063 Failin,D. CP101 2 B
2663628 Kingsley,M. QA140 3 A
2663628 Kingsley,M. CM245 3 B
2663628 Kingsley,M. EQ521 3 A
2663628 Kingsley,M. MK341 3 A
2663628 Kingsley,M. CP101 3 B

My idea is to read in record as map for which ID and Name is the key, and courses as value. As the number of courses are different for each student, create two structures, one for student ID and name; the other for each course; push all the courses of the same student into a vector of structure. So the final format is like
Code:
map < struct IDnName; vector < struct Course> record> Record

My coding flow is:
1) getline of each row; parse it into tokens;
2) assign tokens into struct IDnName and struct Course;
3) push the two structs into map, struct IDnName as key and struct Course as value ;
4) push struct Course into vector if IDnName already exists;
Challenges to me:
1) Is this the right algorithm to handle the situation? If not, which is the right way?
2) For learning purpose, with my coding flow to print the record of each student, I break down the job into two functions, a) key_print() b) val_print(); but I am not sure the parameters should be passed by value or reference, which I always have problem with.
I've attached my code, for which there were too many errors to be listed here when I tried to compile. Hope someone could help me out. Thanks a lot!
# 2  
Old 09-15-2014
You don't use ; in templates, you use ,

map <type1, type2> name;

The "correct" way to do it really depends on how you want to do it, but I'd just boil it down to the bare minumum:

Code:
struct grades {
        string course, credit, grade;
};

map <int, vector < grades > > student_marks;
map <int, string> student_names;

This avoids the problem of using a custom struct/class as the "key" type for a map. You have to define > < = comparison overloads for that to work.

Pure integer keys are much faster anyway.
This User Gave Thanks to Corona688 For This Post:
# 3  
Old 09-16-2014
Then comes to a new thing if two maps are used------they need share the key. While student_names only contains 3 unique entries(structure), student_courses contains 12 entries (structure) that are pushed into three vectors each for a student_names.
Do you mean to assign a new integer to both map?
The next step is to calculate the total credit of courses for each student; calculate the average grades for each student on his/her courses taken so far. So that I though use the string(or student ID) as key for retrieval and calculation.
The compiling error indicated the problem is the map iterator, which seems should be overloaded.
Code:
error: no match for 'operator=' in map_itr=mymap.std::map<_Key, _Tp, _Compare, _Alloc>::begin....
candidate is:
In file included from /usr/include/c++/4.7/map:60:0,
......

This challenge is too big for me at this moment. Thanks anyway!
# 4  
Old 09-16-2014
Any challenge is too big when you take the path of maximum resistance.

This problem is exceptionally kind in giving you a unique, integer ID for each student... That's a gift to be embraced.

The code I gave you wasn't pseudocode. This is how I use it:

Code:
#include <stdio.h>

#include <map>
#include <vector>
#include <string>

using namespace std;

struct grades {
        string course, credit, grade;
};

int main(void)
{

        map<int, vector < grades > > marks;
        map<int, string> names;

        {
                int id=1234;
                const char *name="larry";
                grades grade={"a","b","c"};

                names[id]=name;
                marks[id].push_back(grade);
        }
}

If you wanted to bundle the data together and use it in a 'smart' way instead of updating individual variables, you could put it in a class with multiple members inside it. It still clearly belongs in multiple structures. How many times are you supposed to store someone's name and unique ID?

If you really wanted you could put the name and unique id in a pair<int, string>, which you should be able to plug into map < pair< int, string > , ... >
# 5  
Old 09-16-2014
One of my original purposes of this practice is to experience more on vector and map, especially using a struct as key and vector for value in the map, so that I really did not mean to take the mximum resistance path. I like the slang "There are always more than one way to do it", and I tend to over-think many problems before I get to "take the minimum resistance path", but my always problem is how to find out the minimum resistance path.
Of course each unique student ID should be stored only once but not the student name, cases are students with same name but different ID number.
Thanks anyway and I will try using your method first then go back to the map<struct, vector<struct>> method, only for practice purpose to make a running code. Thanks a lot again!
# 6  
Old 09-16-2014
Quote:
Originally Posted by yifangt
Of course each unique student ID should be stored only once but not the student name, cases are students with same name but different ID number.
So?

Code:
names[1234]="Joe";
names[1235]="Joe";

Two students, same name, zero problems.

Quote:
Thanks anyway and I will try using your method first then go back to the map<struct, vector<struct>> method, only for practice purpose to make a running code. Thanks a lot again!
To make your structure usable in a map, you should define an 'operator <' for it.

Code:
class asdf {
public:
        bool operator <(const asdf &rhs) const {
                // Return true if this class is less than RHS,
                // false otherwise
        }
};

How to do so can be fiendishly complex for complicated data, since you first need a coherent definition of what 'less' even means when comparing two student class records.
# 7  
Old 09-16-2014
To make your structure usable in a map, you should define an 'operator <' for it.
How to do so can be fiendishly complex for complicated data, since you first need a coherent definition of what 'less' even means when comparing two student class records.
Definitely I under-estimated the challenge.
Did not realize this only after another two hours of googling/reading. In my original post there were too many errors to be listed here when I tried to compile. which really discouraged me! (Better now.)
Thanks a lot!

---------- Post updated at 05:41 PM ---------- Previous update was at 02:26 PM ----------

Kind of got lost after discussions and searching.
Originally intended output is like:
Code:
---------------------
2333021 Bokow,R. 
                 NS201 3 A
                 MG342 3 A
                 FA302 1 A 
2574063 Failin,D. 
                 MK106 3 C
                 MA208 3 B
                 CP101 2 B
2663628 Kingsley,M. 
                 QA140 3 A 
                 EQ521 3 A
                 MK341 3 A
                 CP101 3 B

So
1) I want student_ID be the key for the courses and names.
2) The records are read from a fstream which contains hundreds of thousands rows, imagine from a university record.
3) Also the student_ID may NOT be clustered together one row after another, so that read in record from file need to be checked for each entry before it is pushed into map.

Last edited by yifangt; 09-16-2014 at 06:47 PM..
Login or Register to Ask a Question

Previous Thread | Next Thread

9 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Vector normalisation

In AWK For 3 individual vectors of the form: -2.772 -9.341 -2.857 -5.140 -6.597 -1.823 -2.730 -5.615 1.159 I would like to write a script that parses line by line to (i) normalise, (ii) divide by the norm for *each* vector. I.e. sqrt(-2.772^2 + -9.341^2 + -2.857^2)=10.154 ... (4 Replies)
Discussion started by: chrisjorg
4 Replies

2. Programming

vector c++

hello guys. i'm new to c++. i've problem using two dimensional vector. i've a project of making conway's game of life. this is the code that i have made so far. my problem is how can i give a two dimensional vector through main. glider.vec1 = vec; is not correct way to give a two... (2 Replies)
Discussion started by: nishrestha
2 Replies

3. Programming

Array and Vector

Hi all, from my understanding I understand that I can use array in this manner. struct test { int a; int b; int c; }; test testing; //creating an array with the structer type testing.a=1; testing.b=2; testing.c=3; If I'm not wrong we can use array in this manner,... (12 Replies)
Discussion started by: vinzping
12 Replies

4. Programming

Storing C++-struct in file - problem when adding new item in struct

Hi, I have received an application that stores some properties in a file. The existing struct looks like this: struct TData { UINT uSizeIncludingStrings; // copy of Telnet data struct UINT uSize; // basic properties: TCHAR szHost; //defined in Sshconfig UINT iPortNr; TCHAR... (2 Replies)
Discussion started by: Powerponken
2 Replies

5. Solaris

Solaris 8 ssh public key authentication issue - Server refused our key

Hi, I've used the following way to set ssh public key authentication and it is working fine on Solaris 10, RedHat Linux and SuSE Linux servers without any problem. But I got error 'Server refused our key' on Solaris 8 system. Solaris 8 uses SSH2 too. Why? Please help. Thanks. ... (1 Reply)
Discussion started by: aixlover
1 Replies

6. Programming

C++ Map using a Vector as a Value Type?

I modified some code I found on Wikipedia concerning maps to see if it would work before applying it to a project I'm working on that has a similar idea. What I would want is for a user to be able to enter sentences and then be able to distinguish how many times a the person entered a word in a... (4 Replies)
Discussion started by: kcgb20
4 Replies

7. UNIX for Dummies Questions & Answers

How to access a struct within a struct?

Can someone tell me how to do this? Just a thought that entered my mind when learning about structs. First thought was: struct one { struct two; } struct two { three; } one->two->three would this be how you would access "three"? (1 Reply)
Discussion started by: unbelievable21
1 Replies

8. Programming

Vector Traversing

Hi i have the following structure struct S { char Mod_num; char val; char chr_nm_cd; } I am reading a 2GB file and inserting into the structure and writing into a vector. I feel like only vector will be a right option. I tried with multimap but it is memory intensive and hence i... (1 Reply)
Discussion started by: dhanamurthy
1 Replies

9. UNIX for Dummies Questions & Answers

Pressing backspace key simulates enter key

Hi, Whenever i press the backspace key, a new line appears, i.e. it works like a enter key. :confused: Thanks (2 Replies)
Discussion started by: vibhor_agarwali
2 Replies
Login or Register to Ask a Question