the "hat" container class [C++]
From: AngleWyrm (no_spam_anglewyrm_at_hotmail.com)
Date: 05/24/04
- Next message: CBFalconer: "Re: Programming is not as much fun/more fun than it used to be."
- Previous message: Chris Sonnack: "Re: Licenses, was re: What a riot----July 1996 Computer Shopper"
- Next in thread: Craig Nicol: "Re: the "hat" container class [C++]"
- Reply: Craig Nicol: "Re: the "hat" container class [C++]"
- Reply: Zahid Faizal: "Re: the "hat" container class [C++]"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Mon, 24 May 2004 19:17:41 GMT
This container serves a special purpose: To be able to pull a random sample
from a collection, where the chances of each item in the collection are NOT
uniform. It can store any kind of user-defined or standard class object, as
long as the object can be evaluated to an integer.
The value of the objects in the container are the number of "chances" that
object has, to be selected. It's probabability is numChances/totalChances.
And of course totalChances is the sum of all objects.
All critiques are welcome!
/*
* RandomContainer
* stores and returns objects according to specified probabilities
*/
#include <cstdlib>
#include <iostream>
#include <list>
#include <ctime> // time
#include <algorithm> // copy
#include <numeric> // accumulate
#include <iterator> // ostream_iterator
using namespace std;
////////////////////////////////////////////////////////////////////////////
////
// New container: Hat
//
// Interface:
// put(object)
// pull()
// peek()
//
template<class T, class C=list<T> >class hat{
public:
typedef typename C::value_type value_type;
typedef typename C::size_type size_type;
typedef C container_type;
typedef typename container_type::iterator iterator;
protected:
C c;
value_type totalChances;
iterator GetRandom(){
value_type randomPoint = value_type( rand() % totalChances );
cout << "\nrandomPoint = " << randomPoint << " / " <<
totalChances
<< " = " << (float)randomPoint/(float)totalChances << endl;
iterator i;
value_type walker = 0;
for( i = c.begin(); i != c.end(); ++i){
walker += *i;
if( randomPoint <= walker ){
cout << "FOUND: " << randomPoint << " <= " << walker
<< " at " << *i << endl;
break;
}
}
return i;
}
public:
explicit hat(const C& incomingContainer = C() ):c(incomingContainer)
{
totalChances = accumulate( c.begin(), c.end(), 0 ); }
bool empty() const{ return c.empty(); }
size_type size() const { return c.size(); }
void clear() { c.clear(); }
iterator begin(){ return c.begin(); }
iterator end(){ return c.end(); }
template <class InputIterator>
void put( InputIterator f, InputIterator l){
c.insert( c.end(), f, l);
totalChances = accumulate( f, l, totalChances );
}
value_type pull(){
if(c.empty()) return *c.end();
iterator i = GetRandom();
value_type pulledObject = *i;
totalChances -= pulledObject;
c.erase(i);
return pulledObject;
}
value_type& peek(){
return *GetRandom();
}
value_type chances(){ return totalChances; }
// Debugging purposes only
void Display(){
cout << endl;
copy( c.begin(), c.end(), ostream_iterator<int>(cout, " ") );
cout << " size: " << c.size() << " totalChances: " <<
totalChances << endl;
}
};
////////////////////////////////////////////////////////////////////////////
///
// Main
int main(void){
srand( time(NULL) ); rand(); rand();
// create some data and store it in a hat
int data[6] = { 10, 20, 30, 1, 2, 3 }; // set of 'Chances'
hat<int> myHat;
myHat.put( data, data+6 );
myHat.Display();
for(int i = 1; i <= 3; ++i ){
cout << "Pull(): " << myHat.pull() << endl;
myHat.Display();
}
system("pause");
}
- Next message: CBFalconer: "Re: Programming is not as much fun/more fun than it used to be."
- Previous message: Chris Sonnack: "Re: Licenses, was re: What a riot----July 1996 Computer Shopper"
- Next in thread: Craig Nicol: "Re: the "hat" container class [C++]"
- Reply: Craig Nicol: "Re: the "hat" container class [C++]"
- Reply: Zahid Faizal: "Re: the "hat" container class [C++]"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|