Saturday, 18 June 2011
On vacation from coding
Tuesday, 14 June 2011
When true != true
Tuesday, 7 June 2011
Multisets and Multimaps
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
//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;
}
Thursday, 2 June 2011
Example of Multisets
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Simple example of multiset
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
int main()
{
int a[ 10 ] = { 7, 22, 9, 1, 18, 30, 100, 22, 85, 13 };
int aSize = sizeof(a) / sizeof(int);
std::multiset< int, std::less< int > > intMultiset(a, a + aSize);
cout << "Printing out all the values in the multiset : ";
multiset<int>::iterator it;
for ( it = intMultiset.begin(); it != intMultiset.end(); ++it)
cout << " " << *it;
cout << endl << endl;
std::ostream_iterator< int > output( cout, " " );
cout << "There are currently " << intMultiset.count( 15 )
<< " values of 15 in the multiset\n\n";
intMultiset.insert( 15 );
intMultiset.insert( 15 );
cout << "After two inserts, there are currently " << intMultiset.count( 15 )
<< " values of 15 in the multiset\n\n";
cout << "Printing out all the values in the multiset : ";
for ( it = intMultiset.begin(); it != intMultiset.end(); ++it)
cout << " " << *it;
cout << endl << endl;
return 0;
}
Wednesday, 25 May 2011
'auto' and 'register' variables
Here's an excerpt from Section 6.7.1 (footnote 101) of the C99 standard (pdf):
The implementation may treat any
register
declaration simply as anauto
declaration. However,whether or not addressable storage is actually used, the address of any part of an object declared with storage-class specifier register cannot be computed, either explicitly (by use of the unary&
operator as discussed in 6.5.3.2) or implicitly (by converting an array name to a pointer as discussed in 6.3.2.1). Thus, the only operator that can be applied to an array declared with storage-class specifierregister
issizeof
.
And from Section 7.1.1, Paragraph 3 of the C++ standard (pdf):
A
register
specifier has the same semantics as anauto
specifier together with a hint to the implementation that the object so declared will be heavily used. [Note: the hint can be ignored and in most implementations it will be ignored if the address of the object is taken. —end note]
So, this seems like another case of C and C++ having "identical" features that behave the way you'd expect them most of the time, but diverge and cause confusion other times. In this situation, I think the way C does it makes sense since it
- is semantically closest to being correct and;
- doesn't do things behind your back.
Fun tidbits about register
The C++ group (WG21) wants to deprecate register
:
The
register
keyword serves very little function, offering no more than a hint that a note says is typically ignored. It should be deprecated in this version of the standard, freeing the reserved name up for use in a future standard, much likeauto
has been re-used this time around for being similarly useless.Notes from the March, 2009 meeting:
The consensus of the CWG was in favor of deprecating
register
.
Look what the C99 group (WG14) said about register
(pdf) at a meeting:
General agreement to deprecate the “
auto
” keyword. Should we ask WG21 to go back to the previous use of “register
” (no address)? No, this will not fly with WG21.
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>
using namespace std;
int main()
{
int i = 123;
auto int j = 456;
register int k = 789;
cout<<"Address of i = " << &i <<", Value = " << i << endl;
cout<<"Address of j = " << &j <<", Value = " << j << endl;
cout<<"Address of k = " << &k <<", Value = " << k << endl;
return 0;
}
Wednesday, 11 May 2011
Example of set_union and set_intersection
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
int main()
{
int setOne[] = {5, 10, 15, 20, 25};
int setTwo[] = {50, 40, 30, 20, 10, 11, 21, 31, 41, 51};
int setOneSize = sizeof(setOne) / sizeof(int);
int setTwoSize = sizeof(setTwo) / sizeof(int);
//Its necessary to sort if not already sorted
sort(setTwo, setTwo + setTwoSize);
vector<int> unionSetVector(setOneSize + setTwoSize);
set_union(setOne, setOne + setOneSize, setTwo, setTwo + setTwoSize, unionSetVector.begin());
cout<<"\n1. unionSetVector : ";
copy(unionSetVector.begin(), unionSetVector.end(), ostream_iterator<int>(cout, " "));
cout<<endl;
vector<int> intersectionSetVector(min(setOneSize, setTwoSize));
set_intersection(setOne, setOne + setOneSize, setTwo, setTwo + setTwoSize, intersectionSetVector.begin());
cout<<"\n1. intersectionSetVector : ";
copy(intersectionSetVector.begin(), intersectionSetVector.end(), ostream_iterator<int>(cout, " "));
cout<<endl;
cout<<endl;
return 0;
}
Tuesday, 3 May 2011
Example of 'Set' and operations
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>
#include <set>
using namespace std;
int main()
{
int someInts[] = {3, 6, 9, 12, 15, 18};
int someIntsSize = sizeof(someInts) / sizeof(int);
set<int> someSet (someInts, someInts + someIntsSize);
cout<<"\n1. someSet : ";
copy(someSet.begin(), someSet.end(), ostream_iterator<int>(cout, " "));
cout<<endl;
//Insert some more elements
someSet.insert(0);
someSet.insert(10);
someSet.insert(20);
cout<<"\n2. someSet : ";
copy(someSet.begin(), someSet.end(), ostream_iterator<int>(cout, " "));
cout<<endl;
//Upper Bound means the next greater number
set<int>::iterator it = someSet.upper_bound(5);
cout << "\nupper_bound(5) = " << *it << endl;
it = someSet.upper_bound(10);
cout << "\nupper_bound(10) = " << *it << endl;
//Lower bound means either equal or greater number
it = someSet.lower_bound(5);
cout << "\nlower_bound(5) = " << *it << endl;
it = someSet.lower_bound(10);
cout << "\nlower_bound(10) = " << *it << endl;
//Equal Range returns a pair
pair<set<int>::iterator,set<int>::iterator> retIt;
retIt = someSet.equal_range(5);
cout<<"\nequal_range(5) - lower bound = " << *retIt.first <<
" upper bound = " << *retIt.second << endl;
retIt = someSet.equal_range(10);
cout<<"\nequal_range(10) - lower bound = " << *retIt.first <<
" upper bound = " << *retIt.second << endl;
cout<<endl;
return 0;
}
Wednesday, 27 April 2011
Example of Algorithm Copy
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//OutputIterator copy ( InputIterator first, InputIterator last, OutputIterator result );
#include<iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
int someInts[] = {10, 20, 20, 40, 50};
int someMoreInts[] = {100, 200, 300, 400, 500, 600, 700};
vector<int> someVector;
vector<int>::iterator someIterator;
//Get the total size of all elements
int totalSize = (sizeof(someInts) + sizeof(someMoreInts)) / sizeof(int);
//Resize someVector to right size
someVector.resize(someVector.size() + totalSize);
//Get the number of elements of someInts
int tempSize = sizeof(someInts) / sizeof(int);
vector<int>::iterator finalElementIt = copy(someInts, someInts + tempSize, someVector.begin());
cout<<"\n1. someVector contains :";
for(someIterator = someVector.begin(); someIterator != someVector.end(); ++someIterator)
cout<<" "<<*someIterator;
cout<<endl;
//Get size of someMoreInts
tempSize = sizeof(someMoreInts) / sizeof(int);
copy(someMoreInts, someMoreInts + tempSize, finalElementIt);
cout<<"\n2. someVector contains :";
for(someIterator = someVector.begin(); someIterator != someVector.end(); ++someIterator)
cout<<" "<<*someIterator;
cout<<endl;
return 0;
}
Wednesday, 20 April 2011
An Challenging Interview question with a difference
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>
using namespace std;
//This class can be designed as you wish
class SR
{
public:
SR(int i) {}
};
int main()
{
int sum = 0;
for (int i = 1; i < 100; i++)
{
SR ii(i);
while (i--)
sum += i;
}
cout<<"Expected value of sum = 161700" << endl;
cout<<"Returned value of sum = " << sum << endl;
return 0;
}
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>
using namespace std;
//This class can be designed as you wish
class SR
{
public:
SR(int& i):ref(i)
{
var = i;
}
~SR()
{
ref = var;
}
private:
int var;
int &ref;
};
int main()
{
int sum = 0;
for (int i = 1; i < 100; i++)
{
SR ii(i);
while (i--)
sum += i;
}
cout<<"Expected value of sum = 161700" << endl;
cout<<"Returned value of sum = " << sum << endl;
return 0;
}
Tuesday, 12 April 2011
isNumeric()
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
bool isNumeric1(string stringToCheck)
{
bool numeric = false;
if(stringToCheck.find_first_not_of("0123456789.") == string::npos)
numeric = true;
return numeric;
}
bool isNumeric2(string stringToCheck)
{
bool numeric = true;
unsigned i = 0;
while(numeric && i < stringToCheck.length())
{
switch (stringToCheck[i])
{
case '0': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9': case '.':
//do nothing
break;
default:
numeric = false;
}
i++;
}
return numeric;
}
bool isNumeric3(string stringToCheck)
{
stringstream streamVal(stringToCheck);
double tempVal;
streamVal >> tempVal; //If numeric then everything transferred to tempVal
if(streamVal.get() != EOF)
return false;
else
return true;
}
int main()
{
string str1("123"), str2("134.567"), str3("12AB");
cout << "Approach 1" << endl;
cout << str1 << (isNumeric1(str1) ? " is Numeric" : " is Not Numeric") << endl;
cout << str2 << (isNumeric1(str2) ? " is Numeric" : " is Not Numeric") << endl;
cout << str3 << (isNumeric1(str3) ? " is Numeric" : " is Not Numeric") << endl;
cout << "\nApproach 2" << endl;
cout << str1 << (isNumeric2(str1) ? " is Numeric" : " is Not Numeric") << endl;
cout << str2 << (isNumeric2(str2) ? " is Numeric" : " is Not Numeric") << endl;
cout << str3 << (isNumeric2(str3) ? " is Numeric" : " is Not Numeric") << endl;
cout << "\nApproach 3" << endl;
cout << str1 << (isNumeric3(str1) ? " is Numeric" : " is Not Numeric") << endl;
cout << str2 << (isNumeric3(str2) ? " is Numeric" : " is Not Numeric") << endl;
cout << str3 << (isNumeric3(str3) ? " is Numeric" : " is Not Numeric") << endl;
return 0;
}