Hello,

I have a map that contains the alphabet (key) and a double (value) and I would like to sort the list so that the highest value is at the top but it still keeps it's key..

E.g.

#include <iostream>
#include <map>

int main()
{
     map<char, double> alphabet;
     alphabet['a'] = 10.2;
     alphabet['b'] = 20;
     alphabet['c'] = 10;

     return 0;
}

list would be:

B = 20;
A = 10.2
C = 10

Any ideas?

Also, is there a way that will allow the values to be set like a Dictionary in C# e.g.

public map<char, double> alphabet()
{
     // set the values
};

Any help would be amazing, thanks :)

What you are really wanting to do is create a sortable storage form from your map.
The obvious way is to just put the map into a std::vector<std::pair<double,char> and sort on the first value in the pair. Obviously, you can reverse that and sort on the second value.

As for setting, not 100% sure what you want, you certainly can do this:

void setMapFromArray(std::map<char,double>& MObj,const double* DA,const int NSize)
{
  if (NSize<=26)   // assuming that you are not going to do interesting things beyond 26 (yet) 
    {
      char A='a';
      // The map might need to be checked here to determine if it is (a) empty (b) doesn't have
      // have existing entries etc.
      for(int i=0;i<NSize;i++,A++)
        MObj.insert(std::map<char,double>::value_type(A,DA[i]));
    }
   return;
}

Obviously, you can use a typedef, and some templates if you like, or a different input form etc.

Is that enough help?? [well with the first part really] -- and can you give a little more detail on the second part please.

Edited 5 Years Ago by StuXYZ: n/a

Thanks for your reply..

Kinda confused, a map will allow me to have two variable types (char, int) which is what I need to do!
But a vector will allow it? (I'm really new to vectors and maps)

Couldn't I just put the map into a list and then sort it like that?

The map is normally implemented as a set of std::pair<key,value>. The search is then specialised to be just on the key. [Note: there is nothing in the standard that says it must be like this, just this is the common way to do it].

Therefore you can iterate over the set and place it into anything, e.g. a vector or a list. The issues are what you need to do with it afterwards. The vector has the advantage that it is random access, but has cost associated with insertion, so depending on what you want a list might be better. However, if you want to sort something, you typically, need a sequential container which map isn't.

It is also important that the sequential container that you put the map into has both the key and the value, or normally, you have no way to figure out the key again.

Edited 5 Years Ago by StuXYZ: n/a

I kinda get it.. But basically:

I will have two maps that will contain two sets of values:

Alphabet 1 (sorted) Alphabet 2
B = 10 C = 20
A = 3 B = 10
C = 2 A = 4

And then swop them..

B->C
A->B
C->A

Now would it be easier to store them into an array, do a bubble sort to get the (hightest->lowest) values?

This is easy, but I'm confused about maintaining the alphabet values is hard, for example:

If I sorted

A = 10.2;
B = 20;
C = 10;

A would be 20

But I just want B = 20 to come before A

If that makes sense? That's why I thought a map would be easier but clearly not!

If that is all that you want, e.g. a sorted list, then clearly a map is not what you want. A map is basically a quick way to look something up, for example if you need
to find a number that is indexed by name, a map is an excellent option.

However, if you have a sequence, say the letters A to Z, and a number associated with that which determines an order, then you want a sequential object. So in your case, it looks like std::list or std::vector are your first two choices -- this difference really being AFTER you have sorted them, do you need to just get the letters in order, or are you going to need to get say the 12th then the 22nd etc. If it is the former then use a std::list, if not use a std::vector.

Note in your case you have two pieces of linked information, so use a list/vector of pairs of items. More generally, if you have a lot of information, e.g someones name, address etc + a score on a test and you wish to sort on the score, then use a struct/class container that information and a comparitor function [That is code that allows you to compare the class objects and uses the correct number in the class for that comparison].

Hello,

I have a map that contains the alphabet (key) and a double (value) and I would like to sort the list so that the highest value is at the top but it still keeps it's key..

E.g.

#include <iostream>
#include <map>

int main()
{
     map<char, double> alphabet;
     alphabet['a'] = 10.2;
     alphabet['b'] = 20;
     alphabet['c'] = 10;

     return 0;
}

list would be:

B = 20;
A = 10.2
C = 10

Any ideas?

Also, is there a way that will allow the values to be set like a Dictionary in C# e.g.

public map<char, double> alphabet()
{
     // set the values
};

Any help would be amazing, thanks :)

Someone correct me if I'm wrong but since he wants it sorted by value rather than key... then instead of inserting the (key, value) pairs in a map, insert the (value, key) pairs into a multimap.

> ... then instead of inserting the (key, value) pairs in a map, insert the (value, key) pairs into a multimap.

Would have to programmatically take care of the keys being unique, which makes it a bit messy.


Use Boost Bimap, perhaps?
http://www.boost.org/doc/libs/1_48_0/libs/bimap/doc/html/index.html

Something like:

#include <iostream>
#include <boost/bimap/bimap.hpp>
#include <boost/bimap/multiset_of.hpp>

int main()
{
    using namespace boost::bimaps ;
    typedef bimap< char, multiset_of< int, std::greater<int> > > map_type ;
    typedef map_type::value_type value_type ;

    map_type alphabet ;
    alphabet.insert( value_type( 'a', 30 ) ) ;
    alphabet.insert( value_type( 'b', 50 ) ) ;
    alphabet.insert( value_type( 'c', 40 ) ) ;
    alphabet.insert( value_type( 'd', 70 ) ) ;
    alphabet.insert( value_type( 'e', 40 ) ) ;

    const auto& map_char_to_int = alphabet.left ;
    for( auto iter = map_char_to_int.begin() ; iter != map_char_to_int.end() ; ++iter )
        std::cout << iter->first << ' ' << iter->second << "  " ;
    std::cout << '\n' ;
    // a 30  b 50  c 40  d 70  e 40

    const auto& map_int_to_char = alphabet.right ;
    for( auto iter = map_char_to_int.begin() ; iter != map_char_to_int.end() ; ++iter )
        std::cout << iter->first << ' ' << iter->second << "  " ;
    std::cout << '\n' ;
    // 70 d  50 b  40 c  40 e  30 a
}
This article has been dead for over six months. Start a new discussion instead.