473,664 Members | 2,967 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Playing with Multimap

21 New Member
Lets suppose I want to get only the first key value pair of each key.

I mean in refernce to the below example something like this:
Expand|Select|Wrap|Line Numbers
  1. Johnson, J. 12345
  2. Smith, P. 54321
OR I want to print only the last values like this:-
Expand|Select|Wrap|Line Numbers
  1. Johnson, J. 10000
  2. Smith, P. 60000
How can I do this ?
Here is what I have till now.

Expand|Select|Wrap|Line Numbers
  1. typedef multimap <char*, long, compare> MMap;
  2.  
  3. void main()
  4. {
  5.      MMap D;
  6.      D.insert(MMap::value_type("Johnson,J.", 12345));
  7.      D.insert(MMap::value_type("Smith,P.", 54321));
  8.      D.insert(MMap::value_type("Johnson,J.", 10000));
  9.      D.insert(MMap::value_type("Smith,P.", 20000));
  10.      D.insert(MMap::value_type("Smith,P.", 60000));
  11.  
  12.      MMap::iterator ii;
  13.      for(ii=D.begin(); ii!=D.end(); ii++)
  14.      {
  15.           cout<< (*ii).first<< " "<<
  16.                      (*ii).second<<endl;
  17.      }
  18.      cout<<"There are "<<D.size()<<" elements.\n";
  19. }
  20.  
Output:
Johnson, J. 12345
Johnson, J. 10000
Smith, P. 54321
Smith, P. 20000
Smith, P. 60000
There are 5 elements.

Thanks
Oct 8 '09 #1
8 3653
Banfa
9,065 Recognized Expert Moderator Expert
I think I would say that you have chosen the wrong data type. You actually want a relationship between records with the same key, however multimap does not implement this, it just allows non-unique keys in the map but there is no implied relationship between items with the same key.

rather than multimap<char *, long> maybe you should consider something different such as map<char *, list<long> >. That is a map of unique keys where each key has a list of associated long values. Then it would be easy to extract the first long value for each key.

Just a thought, obviously I do not know your whole system design so I can't truely tell how suitable this approach is.
Oct 8 '09 #2
Banfa
9,065 Recognized Expert Moderator Expert
By the way using you multimap as written you would have to iterate through the multimap and each time you print an entry first check to see if you have already printed an entry for that key and if not print the entry and temporarily store the key in a list of printed keys.
Oct 8 '09 #3
weaknessforcats
9,208 Recognized Expert Moderator Expert
What you have to do is extract all of the pairs with the duplicate keys.

You do this using multimap::lower _bound and multimap::upper _bound.

multimap::lower _bound returns an iterator to the first pair with that key.
multimap::upper _bound returns an intrerator one beyond the last pair with that key.

Now you can run a loop using the two iterators in the same way that you use the begin and end iterators and pick out the correct record.

BTW, there is an equal_range algorithm that calls multimap::lower _bound and
multimap::upper _bound for you ans returns a pair where first is the iterator returned from multimap::lower _bound and second is the iterator returned from multimap::upper _bound.

I would ditch your code and start over.
Oct 8 '09 #4
cowboyrocks2009
17 New Member
Great :) good suggestions.
Oct 9 '09 #5
crochunter
21 New Member
Thanks guys :) I am very happy to get some guidance finally :) I discussed this problem with many people but unfortunately didn't get any replies.
I will start over again and post my codes for your cross checking..

Thanks
Oct 9 '09 #6
crochunter
21 New Member
Hi do you mean something like this :-

Expand|Select|Wrap|Line Numbers
  1. // multimap::count
  2. #include <iostream>
  3. #include <map>
  4. using namespace std;
  5.  
  6. int main ()
  7. {
  8.   multimap<char,int> mymm;
  9.   multimap<char,int>::iterator it;
  10.   char c;
  11.  
  12.   mymm.insert(pair<char,int>('x',50));
  13.   mymm.insert(pair<char,int>('y',100));
  14.   mymm.insert(pair<char,int>('y',150));
  15.   mymm.insert(pair<char,int>('y',200));
  16.   mymm.insert(pair<char,int>('z',250));
  17.   mymm.insert(pair<char,int>('z',300));
  18.  
  19.   for (c='x'; c<='z'; c++)
  20.   {
  21.     cout << "There are " << (int)mymm.count(c);
  22.     cout << " elements with key " << c << ":";
  23.     for (it=mymm.equal_range(c).first; it!=mymm.equal_range(c).second; ++it)
  24.       cout << " " << (*it).second;
  25.     cout << endl;
  26.   }
  27.  
  28.   return 0;
  29. }
I am working on this to enhance for my purpose.

The results come something like this :-

Expand|Select|Wrap|Line Numbers
  1. There are 1 elements with key x: 50
  2. There are 3 elements with key y: 100 150 200
  3. There are 2 elements with key z: 250 300
I can see some hope there I guess :)

Thanks
Oct 9 '09 #7
crochunter
21 New Member
Ok I am able to build a logic which does exactly how I wanted it to work but when I add more records there are some problems in flagging.

Here is and example:-
when my input is :

Expand|Select|Wrap|Line Numbers
  1.   mymm.insert(pair<char,int>('a',50));
  2.   mymm.insert(pair<char,int>('b',100));
  3.   mymm.insert(pair<char,int>('b',150));
  4.   mymm.insert(pair<char,int>('b',200));
  5.   mymm.insert(pair<char,int>('c',250));
  6.   mymm.insert(pair<char,int>('c',300));
  7.   mymm.insert(pair<char,int>('d',300));
output is correct :-
Expand|Select|Wrap|Line Numbers
  1. single      50
  2. starterminal       100
  3. middle       150
  4. terminal       200
  5. starterminal       250
  6. terminal       300
  7. single      300
But when I change my input like this:-
Expand|Select|Wrap|Line Numbers
  1.   mymm.insert(pair<char,int>('a',50));
  2.   mymm.insert(pair<char,int>('b',100));
  3.   mymm.insert(pair<char,int>('b',150));
  4.   mymm.insert(pair<char,int>('b',200));
  5.   mymm.insert(pair<char,int>('c',250));
  6.   mymm.insert(pair<char,int>('c',300));
  7.   mymm.insert(pair<char,int>('d',300));
  8.   mymm.insert(pair<char,int>('e',250));
  9.   mymm.insert(pair<char,int>('e',300));
The output is not correct:-

Expand|Select|Wrap|Line Numbers
  1. single      50
  2. starterminal       100
  3. middle       150
  4. terminal       200
  5. starterminal       250
  6. terminal       300
  7. single      300
  8. terminal       250
  9. terminal       300
Here is my code:-
Expand|Select|Wrap|Line Numbers
  1. // multimap::count
  2. #include <iostream>
  3. #include <map>
  4. #include<vector>
  5. using namespace std;
  6.  
  7. int main ()
  8. {
  9.   multimap<char,int> mymm;
  10.   multimap<char,int>::iterator it;
  11.   multimap<char, int>::const_iterator m1_cIter;
  12.   char c;
  13.  
  14.   mymm.insert(pair<char,int>('a',50));
  15.   mymm.insert(pair<char,int>('b',100));
  16.   mymm.insert(pair<char,int>('b',150));
  17.   mymm.insert(pair<char,int>('b',200));
  18.   mymm.insert(pair<char,int>('c',250));
  19.   mymm.insert(pair<char,int>('c',300));
  20.   mymm.insert(pair<char,int>('d',300));
  21.   mymm.insert(pair<char,int>('e',250));
  22.   mymm.insert(pair<char,int>('e',300));
  23.  
  24.  
  25.   int i = 0;
  26.   int k = 0;
  27.   for (c='a'; c<='z'; c++)
  28.   {
  29.     for (it=mymm.equal_range(c).first; it!=mymm.equal_range(c).second; ++it)
  30.       if((int)mymm.count(c)>2){      
  31.          if(i==0){
  32.             cout << "start"<<"\t"<<(*it).second << endl;
  33.          }    
  34.          else if(i>0 && i < ( mymm.count(c) - 1)){
  35.             cout << "middle"<<"\t"<<(*it).second << endl;
  36.          }
  37.          else {     
  38.             cout << "terminal"<<"\t"<<(*it).second << endl;
  39.          }
  40.        i++;
  41.       }
  42. /////////////
  43.       else if((int)mymm.count(c)==1){      
  44.             cout << "single"<<"\t"<<(*it).second << endl;   
  45.       }
  46. /////////////
  47. /////////////
  48.       else if((int)mymm.count(c)==2){      
  49.          if(k==0){
  50.             cout << "start" << "\t"<< (*it).second << endl;
  51.          }
  52.          else {
  53.             cout << "terminal" << "\t" << (*it).second << endl; 
  54.          } 
  55.          k++;
  56.       }
  57. ////////////
  58.   }
  59.   return 0;
  60. }
Can you point out the where I am making the mistake ?
One more thing if I change <char, int> to <string , string> will it work ? What changes do I need to make ?
Expand|Select|Wrap|Line Numbers
  1.   mymm.insert(pair<string,string>("a","50"));

Thanks and do reply :)
Oct 12 '09 #8
Banfa
9,065 Recognized Expert Moderator Expert
The problem is your use of k and i, you would have a similar problem if you had a second group of 3 or more.

This is because you only ever initialise i and k once before the loop.

In fact use of k and i is, in my opinion, poor design. You would be much better off testing your iterator against the end conditions mymm.equal_rang e(c).first and mymm.equal_rang e(c).second. That would also allow you to reduce you loop complexity by reducing the program to 2 conditions inside the loop, 1 and more than 1 rather than 1, 2 and more than 2. Actually eliminating i or k and correctly initialising the other may allow a similar reduction.


And on a final but not directly related note this is definitely poor practice

for (c='a'; c<='z'; c++)

The problem is that while C and C++ does guarantee that '0' + 1 == '1' and '1' + 1 == '2' up to '8' + 1 == '9', i.e. does guarantee that if you add 1 onto a character representation of a digit that you get the next digit it does not guarantee that

'a' + 1 == 'b'

and in fact there are some platforms where you loop will not work because they use a run time character set where the letters are not contiguous.

You should avoid any code relying on 'a' + 1 == 'b' in production code especially if it has to be portable. You can easily get round it with a vector of char.
Oct 12 '09 #9

Sign in to post your reply or Sign up for a free account.

Similar topics

12
13449
by: Tanguy Fautré | last post by:
Hello, does std::multimap make any guarantee about the insertion order? for example: int main() { std::multimap<int, int> Map;
9
7857
by: Dennis Jones | last post by:
Hi, Is there a way to iterate through a multimap in such a way as to encounter only the unique keys? In other words, since a multimap allows duplicate keys, I would like to iterate through the entire multimap, and if a particular key has duplicates, only see one of them. I don't think I care about which of the duplicate entries I see, because once I have an entry, I can use lower_bound and upper_bound to iterate through them, right? ...
3
6294
by: He Shiming | last post by:
Hi Folks, Happy holidays! I have a question regarding STL multimap. Basically, the current multimap<int,int> look like this: key=>value 1=>10, 1=>20, 1=>30,
3
6069
by: Przemek | last post by:
All, what is the efficient way to find all distinct keys in a multimap. I use the code template<class T1, class T2> set<T1> GetDistinctKeys(multimap<T1, T2> nMap) { T1 temp; multimap<T1, T2>::iterator i_ptr;
4
4498
by: Nick Keighley | last post by:
Hi, I've checked out various documentation for multimap but can't find anywhere it explicitly stated that insert() invalidates multimap iterators. consider this pseudo code:- int DataItem::genDerived () {
4
4228
by: sks | last post by:
I have a question regarding std::multimap/iterators. At the SGI website, it says "Erasing an element from a multimap also does not invalidate any iterators, except, of course, for iterators that actually point to the element that is being erased." I design/implemented a observer pattern that is priority based. It so happened that observers were deregistering themselves while they were being notified. In other words, we were iterating...
1
2711
by: Saile | last post by:
I want to give an array the values from the specific multimap's key's values. multimap<string,int> mymultimap; multimap<string,int>::iterator it; pair<multimap<string,int>::iterator,multimap<string,int>::iterator> ret; mymultimap.insert (pair<string,int>("test",10)); mymultimap.insert (pair<string,int>("test",20)); mymultimap.insert (pair<string,int>("ab",100)); mymultimap.insert (pair<string,int>("ab",200));
1
2228
by: ambarish.mitra | last post by:
Hi all, I have a multimap, where key is an int and the value is a class. I can insert into the multimap, but finding it difficult to retrieve the value when keys match. I can do this with primitive types (int/char etc). Example: class A {
20
3976
by: puzzlecracker | last post by:
I am using while loop for that but I am sure you can do it quicker and more syntactically clear with copy function. Here is what I do and would like to if someone has a cleaner solution: vector<stringvec; multimap<stirng, intmyMap // populate myMap
0
8348
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8861
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
8549
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8636
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6187
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5660
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4351
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2764
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2003
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.