Showing posts with label Multimap. Show all posts
Showing posts with label Multimap. Show all posts

Tuesday, 7 June 2011

Multisets and Multimaps

I was trying to understand where multisets would be used as compared to multimaps and I didnt find any straightforward answer. I found this simple explanation at StackOverflow:

multimap

  • With ZIP code as a key, all people which have that ZIP code
  • With account ID as key, all open orders of that person/account
  • A dictionary, with per keyword various explanations

multiset

is in essence a map with a key and a integer count.

  • The inventory of a shop, all products have their key and the amount still available is the value
  • accumulated sales data of a shop, every time a product is sold the product id get's added to the multiset thereby increasing the amount sold

As a result I created this example below. This is probably not the best of examples but I didnt want to change it. The main problem below is that multimap's are not strictly speaking required in the example below. I could have used a map. Multimap would be needed if there was no quantity_ in the class and then I can add the products one by one. I could have then used the count method to get the quantity.

Anyway, program as follows:


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Simple example of multiset

#include <iostream>
#include <string>
#include <set>
#include <map>
#include <algorithm>

using namespace
std;

class
Product //Keeping this simple
{
public
:
Product(string name, int code, int price) :
name_(name), productCode_(code), price_(price)
{

quantity_ = 10; //Lets fix this value for simplicity
}
bool
availableForSale()
{

if
(quantity_ > 0)
{

quantity_--;
return
true;
}

return
false;
}

string name_;
int
productCode_;
int
price_;
int
quantity_;
private
:
Product(); //Disabled the default constructor
};

void
sellProduct(string name, multimap<string, Product*>& inventory, multiset <int> &soldItems)
{

multimap<string, Product*>::iterator it = inventory.find(name);
if
(it != inventory.end())
{

if
((*it->second).availableForSale())
{

soldItems.insert((*it->second).productCode_);
}
}

else

{

cout << "Unknown product : " << name << endl;
}
}


void
soldItemsList(multimap<string, Product*>& inventory, multiset <int> &soldItems)
{

multimap<string, Product*>::iterator it = inventory.begin();
for
(it = inventory.begin(); it != inventory.end(); ++it)
{

int
soldCount = soldItems.count((*it->second).productCode_);
cout<<"Product = " << (*it->second).name_ << ", Quantity Sold = " << soldCount << endl;
}
}


int
checkSales(multimap<string, Product*>& inventory, multiset <int> &soldItems)
{

int
totalSales = 0;
multimap<string, Product*>::iterator it;
for
(it = inventory.begin(); it != inventory.end(); ++it)
{

int
soldCount = soldItems.count((*it->second).productCode_);
totalSales += soldCount * (*it->second).price_;
}

return
totalSales;
}


int
main()
{

//There is no special reason to use multimap instead of a map
//If you wanted to add same product and create quantity multimap is required
multimap<string, Product*> inventory;
Product* prod1 = new Product("product1", 2334, 10);
Product* prod2 = new Product("product2", 4556, 50);
inventory.insert(pair<string, Product*>("product1",prod1));
inventory.insert(pair<string, Product*>("product2",prod2));

multiset <int> soldItems;

sellProduct("product1", inventory, soldItems);
sellProduct("product2", inventory, soldItems);
sellProduct("apple", inventory, soldItems);
sellProduct("product1", inventory, soldItems);
sellProduct("product1", inventory, soldItems);
sellProduct("product2", inventory, soldItems);

soldItemsList(inventory, soldItems);

cout<<"Total sales = " << checkSales(inventory, soldItems) << endl;

delete
prod1;
delete
prod2;
return
0;
}



The output as follows:

Friday, 14 August 2009

Instantiating a Multimap inside a class

The following is a very simple example of Instantiating a Multimap. This example was posted as a result of a comment on the actual Multimap example here.




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This program shows use of multi-maps in a class
#include<iostream>
#include<map>
#include <string>

using namespace
std;

class
mapInstantiator
{

public
:
~
mapInstantiator();
void
createMultiMap(void);
void
insertElements(pair<string, int> element);
void
printer(void);
private
:
multimap<string, int> *phoneNums;
};


void
mapInstantiator::createMultiMap(void)
{

//Instantiate
phoneNums = new multimap<string, int>;
}


void
mapInstantiator::insertElements(pair<string, int> element)
{

phoneNums->insert(element);
}


void
mapInstantiator::printer(void)
{

cout<<"\n\nMultimap printer method"<<endl;
cout<<"Map size = "<<phoneNums->size()<<endl;
multimap<string, int>::iterator it = phoneNums->begin();
while
(it != phoneNums->end())
{

cout<<"Key = "<<it->first<<" Value = "<<it->second<<endl;
it++;
}
}


mapInstantiator::~mapInstantiator()
{

//Dont forget to delete the pointer
delete phoneNums;
}


int
main()
{

mapInstantiator aClass;
aClass.createMultiMap();

//Insert key, value as pairs
aClass.insertElements(pair<string, int>("Joe",123));
aClass.insertElements(pair<string, int>("Will",444));
aClass.insertElements(pair<string, int>("Joe",369));
aClass.insertElements(pair<string, int>("Joe",812));
aClass.insertElements(pair<string, int>("Will",4556));
aClass.insertElements(pair<string, int>("Smith",71));

aClass.printer();

return
0;
}


The Output is as follows:


Thursday, 2 April 2009

An example of C++ Multimap

The following is a simple example of C++ Multimap class.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This program shows use of multi-maps
//We input multiple phone numbers for different people
#include<iostream>
#include<map>
#include <string>

using namespace
std;

//forward declaration
void printer(multimap<string, int> pN);

int
main()
{

multimap<string, int> phoneNums;

//Insert key, value as pairs
phoneNums.insert(pair<string, int>("Joe",123));
phoneNums.insert(pair<string, int>("Will",444));
printer(phoneNums);

//Insert duplicates
phoneNums.insert(pair<string, int>("Joe",369));
phoneNums.insert(pair<string, int>("Smith",567));
phoneNums.insert(pair<string, int>("Joe",888));
phoneNums.insert(pair<string, int>("Will",999));
printer(phoneNums);

//Checking frequency of different keys
cout<<"\n\nFrequency of different names"<<endl;
cout<<"Number of Phones for Joe = "<<phoneNums.count("Joe")<<endl;
cout<<"Number of Phones for Will = "<<phoneNums.count("Will")<<endl;
cout<<"Number of Phones for Smith = "<<phoneNums.count("Smith")<<endl;
cout<<"Number of Phones for Zahid = "<<phoneNums.count("Zahid")<<endl;

//Print all Joe from the list and then erase them
pair<multimap<string,int>::iterator, multimap<string,int>::iterator> ii;
multimap<string, int>::iterator it; //Iterator to be used along with ii
ii = phoneNums.equal_range("Joe"); //We get the first and last entry in ii;
cout<<"\n\nPrinting all Joe and then erasing them"<<endl;
for
(it = ii.first; it != ii.second; ++it)
{

cout<<"Key = "<<it->first<<" Value = "<<it->second<<endl;
}

phoneNums.erase(ii.first, ii.second);
printer(phoneNums);

return
0;
}


//This method prints the vector
void printer(multimap<string, int> pN)
{

cout<<"\n\nMultimap printer method"<<endl;
cout<<"Map size = "<<pN.size()<<endl;
multimap<string, int>::iterator it = pN.begin();
while
(it != pN.end())
{

cout<<"Key = "<<it->first<<" Value = "<<it->second<<endl;
it++;
}
}




The output is as follows: