1

I have a situation where I have to store marks of some students in descending order. So created a map<marks,string>. As a map stores data in the form of heap, always highest mark will be on top. But the problem arises when I have same mark for two students and I have to then rank them on the basis of their name (Alphabetical order considering their name's first letter).

What I did: I separated the marks and names into another map this time with key as name and mark as value. And then printed the new map in the reverse way. And then continued from where I left in the old map. But this requires creation of extra map and involves lot of processing.

My question Is there a better way to do this?

Midhun
  • 744
  • 2
  • 15
  • 31

4 Answers4

0

You could create a map<marks, list<string> > or something similar to store all names for one mark there. Lists come with a sort method, so you can sort all lists that have more than one entry. If you insert them all at a time, you can

  1. create a list if the key is not present

  2. append the name to the mark's list

  3. iterate over all keys

    1. sort the value if larger than 1

    2. print.

starturtle
  • 699
  • 8
  • 25
0

What I would do is to have a map like this :

map<marks, vector<string>>

As this, each mark is binded to a sorted array of students. Everytime you want to insert a new student into a vector, you simply need to find the right index to keep your vector sorted (Dichotomic search is the fastest)

You can also use list<string> instead of vector

Omar
  • 943
  • 6
  • 9
0

Basically you need a Map that can store duplicate keys(int) in non-ascending order and values(string) in non-descending order.

I have a situation where I have to store marks of some students in descending order.

Use std::greater so that the keys will be stored in descending order:

std::map<int, string, std::greater<int> > m;

But the problem arises when I have same mark for two students.

Use Multimap instead of Map. Multimap stores duplicate keys and that is its specialty.

std::multimap<int, string, std::greater<int> > m;

I have to then rank them on the basis of their name (Alphabetical order considering their name's first letter).

Store the value of identical-keys in map in a vector > sort the vector > insert the sorted vector back into map. Note that, inside multimap, you don't need to worry about changing the keys or its order. Values are the only ones whose order is going to be changed (that too only within same-valued-key).

Demo

multimap<int, string, greater<int> >:: iterator it = m.begin(), st;  //Stores duplicate keys(marks).
vector<string> vec;
int lastKey = INT_MAX;
while(it != m.end())
{
    if(it->first < lastKey)
    {
        //Sort the Names
        sort(vec.begin(), vec.end());
        for(int i = 0; i < vec.size(); i++){
            st->second = vec[i];
            st++;
        }
        st = it;
        vec.clear();
    }
    vec.push_back(it->second); //Insert name
    lastKey = it->first;       //marks of last inserted name.
    it++;
}
//Do same for the last(lowest valued key in map) key.
sort(vec.begin(), vec.end());
for(int i = 0; i < vec.size(); i++){
    st->second = vec[i];
    st++;
}
Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
0

You may just use set<pair<mark, string>/*optional appropriate-comparator*/>. It'll sort using marks first, then names.

It'll still be O(log n) for sorted insertion contrary to sorted vector solution

RiaD
  • 46,822
  • 11
  • 79
  • 123