MESSAGE
DATE | 2011-05-19 |
FROM | Ruben Safir
|
SUBJECT | Re: [NYLXS - HANGOUT] C++ Workshop - creating a distribution list
|
The key function in creating a distribution list in out project is the function that exists in the stats namespace, but which is not a member of the Distribution class:
template void mount_individual_data_point(chainlist::List * tabulate, chainlist::List > * table){ T val; stats::Distribution * j; val = *(tabulate->cursor()->value()); //get a value table->cursor()= table->front(); //check to see if the //distribution list exists if(!table->cursor()){ // if not add a distribution table to the //List of distributions j = new stats::Distribution (val); table->insert(*j ); //now we have at least one delete j; j=table->cursor()->value();//and increased its population j->increase_occ(); }else{ //otherwise search for a distribution node described as //value table->find_value(val); if( table->cursor() ){ j=table->cursor()->value();//and increase its population j->increase_occ(); }else{//otherwise add a new node j = new stats::Distribution (val); table->insert( *j ); //now we have one for that value delete j; j=table->cursor()->value();//and increased its population j->increase_occ(); } } }
A detailed look at this templated function is valuable. The purpose of stats:: mount_individual_data_point(chainlist::List *, chainlist::List *) is to take two lists, one of type T, which in our working example translates to integers, and to walk through it creating or growing a second List of type stats::Distribution. As the function walks through the first list, it hunts for unique new samples, and tallys their population in the list in the List::Distribution. Buy sending both lists by pointer, we avoid uneeded copy overhead.
it starts be declaring in int val, which is just for later readability and convience, which holds the current value that we are examining.
values in our List class are pointers, so we copy by value the deferenced value into val.
we then create a pointer to a stats::Distribution object which we use to construct new Distribution objects and destroy them as needed, preventing memory leaks.
stats::Distribution * j;
This just then uses the List's cursor to find where in the list we want to analyze. This is set by the calling function. as mount_individual_data_point only works on a single member of the population at a time.
val = *(tabulate->cursor()->value()); //get a value
we then check to see if our Distribution list is populated. It is up to the user of this function to assure that the Distribution List is actually allocated and not just a pointer, otherwise the infix operation will fail:
table->cursor()= table->front();
If cursor is equal to front, then we haven't done anything to the list yet, it is an empty shell
if(!table->cursor()){ // if not add a distribution table to the List of distributions j = new stats::Distribution (val); table->insert(*j ); //now we have at least one delete j; j=table->cursor()->value();//and increased its population j->increase_occ();
Keep in mind that cursor will equal zero if pointed at front, if no members have yet been added, and so we start by creating a new Distrubution object pointed to (j) with value val, insert it in our List > * table, passing j by value, and then clean up by deleting j.
Finally we pass the address of the new internal Distribution Node within table back to (j), which is a pointer, and call the Distribution member increase_occ() which incrememnt the population tally represented in the private data as int occurances of the Distribution class.
Now if it is not a fresh List< Distribution >, then we need to search to see if out Distribution node already exists. We do this by leveraging our chainlist::List member find_value() which sets the cursor of the list to the first occurance of a value. Since the List< Distribution > has all unique members, we only need to find the first occurance. If the value doesn't exist in the List, then the function set the cursor to NULL
}else{ //otherwise search for a distribution node described as //value table->find_value(val); if( table->cursor() ){ j=table->cursor()->value();//and increase its population j->increase_occ(); }else{//otherwise add a new node j = new stats::Distribution (val); table->insert( *j ); //now we have one for that value delete j; j=table->cursor()->value();//and increased its population j->increase_occ(); } } }
Any questions?
Ruben
|
|