Solved

STL: Multimap sorting both key and value

Posted on 2002-07-29
8
5,615 Views
Last Modified: 2013-12-14
I've written a small program uses the multimap. The program and its output are as follows:

#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

class compare
{
public:
     bool operator()(const char* s, const char* t) const
     {
          return strcmp(s,t)<0;
     }
};

typedef multimap <char*, long, compare> MMap;

void main()
{
     MMap D;
     D.insert(MMap::value_type("Johnson,J.", 12345));
     D.insert(MMap::value_type("Smith,P.", 54321));
     D.insert(MMap::value_type("Johnson,J.", 10000));
     D.insert(MMap::value_type("Smith,P.", 20000));
     D.insert(MMap::value_type("Smith,P.", 60000));

     MMap::iterator ii;
     for(ii=D.begin(); ii!=D.end(); ii++)
     {
          cout<< (*ii).first<< " "<<
                     (*ii).second<<endl;
     }
     cout<<"There are "<<D.size()<<" elements.\n";
}

Output:
Johnson, J. 12345
Johnson, J. 10000
Smith, P. 54321
Smith, P. 20000
Smith, P. 60000
There are 5 elements.

The multimap is sorted according to its key only. How to do sort on both key and value. It should sort on the key value first and if it is the same, then it should sort according to the value.

The output which I expect is as follows:
Johnson, J. 10000
Johnson, J. 12345
Smith, P. 20000
Smith, P. 54321
Smith, P. 60000
There are 5 elements.




0
Comment
Question by:tiagrajah
  • 4
  • 4
8 Comments
 
LVL 5

Expert Comment

by:proskig
ID: 7187856
Unfortunately you cannot do that with standard STL multimap. You can do several other things:

1. Change value. Instead of multimap <char*, long, compare> you can use something like
map<char*, set<long, less<long> > >
The rest of the code should be changed accordingly
D.insert(MMap::value_type("Smith,P.", 54321));
becomes
D[MMap::value_type("Smith,P.")].insert(54321));

2. Change key. For example, make pair<string, long> as a key and implement compare function, which compares strings first and then long. Not obvious what should be a value for your example, but probably you showed us only a part of  your code

3. The most complicated: implement your own RB tree where you can specify sorting criterion and implement your own multimap which uses your tree.
0
 

Author Comment

by:tiagrajah
ID: 7188147
I'm quite new to STL. I find quite difficult to understand the changes you've commented. Can you insert your comments into the code and show me its output?
0
 
LVL 5

Expert Comment

by:proskig
ID: 7188441
An example which should get you started.
Remember, we are here to help, not to make work for you.

class compare
{
public:
  bool operator()(pair<string, long> p1, pair < string, long> p2) const
  {
    if (p1.first == p2.first)
      return p1.second < p2.second;
    else
      return p1.first < p2.first;
  }
};

typedef set<pair<string, long>, compare > MMap;

int main(int argc, char* argv[])
{
  MMap D;
  D.insert(make_pair<string, long>("Smith", 10));
  D.insert(make_pair<string, long>("Smith", 20));
  D.insert(make_pair<string, long>("Smith", 15));

  MMap::const_iterator iter(D.begin());
  MMap::const_iterator end(D.end());
  for (; iter != end; ++iter)
    cout << iter->first << " " << iter->second << std::endl;
}
0
 

Author Comment

by:tiagrajah
ID: 7188485
I have two questions:

1.In your first comment, you suggested to use as follows;
   
    map<char*, set<long, less<long> > >
and
    D[MMap::value_type("Smith,P.")].insert(54321));

But the source code in your 2nd comment, implements the concept in a different way. It uses:
    set<pair<string, long>, compare >

Why? What's wrong with the earlier one?

2. I compiled the source code which you've provided using VC++ 6.0 and it return 23 errors. The first and common error is: ERROR C2784

error C2784: 'bool __cdecl std::operator ==(const class std::multimap<_K,_Ty,_Pr,_A> &,const class std::multimap<_K,_Ty,_Pr,_A> &)' : could not deduce template argument for 'const class std::multi
map<_K,_Ty,_Pr,_A> &' from 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >'

0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 5

Expert Comment

by:proskig
ID: 7190090
1. My source code is a modification of a second approach (make pair<string, long>).  First approach should be very  easy to implement.
2. My code compiles fine on VC++ 6.0. You probably need to add inlcudes and using namespace std; If you still have a problem repost code and show which line causes a trouble.
0
 

Author Comment

by:tiagrajah
ID: 7190101
Ok this the code which I used for compilation.

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
using namespace std;

class compare
{
public:

//the error is over here
 bool operator()(pair<string, long> p1, pair < string, long> p2) const
 {
   if (p1.first == p2.first)
     return p1.second < p2.second;
   else
     return p1.first < p2.first;
 }
};

typedef set<pair<string, long>, compare > MMap;

void main(int argc, char* argv[])
{
 MMap D;
 D.insert(make_pair<string, long>("Smith", 10));
 D.insert(make_pair<string, long>("Smith", 20));
 D.insert(make_pair<string, long>("Smith", 15));

 MMap::const_iterator iter(D.begin());
 MMap::const_iterator end(D.end());
 for (; iter != end; ++iter)
   cout << iter->first << " " << iter->second << std::endl;
}
0
 
LVL 5

Accepted Solution

by:
proskig earned 50 total points
ID: 7190511
#include <string>


is  missing
0
 

Author Comment

by:tiagrajah
ID: 7200524
Yes your code works.

I'll accept ur comment as answer. Thank you very much.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Eclipse and java version isssue 2 38
Use tracing facilities in your browser steps 2 109
eclipse package explorer vs project explorer view 2 74
oracle 11g 23 47
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

919 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now