Re: std::set as search tree - manipulate elements?
On 17 Jul, 08:54, Rune Allnor <all...@tele.ntnu.no> wrote:
Hi all.
I would like to use std::set to implement a histogram.
In essence the histogram contains some elements
struct histbin{
int bin;
int count;
/* constructors */
bool operator<(const histbin& h) const {return bin < h.bin;};
};
where histbin::bin denotes the range of each bin and
histbin::count denotes the number of hits.
The problem is how to build the histogram. Since
std::set is specified to have O(log n) search time,
it must necessarily be implemented as some sort of
tree structure. I would like to exploit this to do
something like
std::set<histbin> histogram;
std::set<histbin>::iterator i;
while (/* data coming in */)
{
i=histogram.find(data);
if (i!=histogram.end())
{
(*i).count+=1; // <<<<<======
}
else
{
/* insert new bin */
}
}
The problem is the tagged line. Apparently, all elements
in std::set are declared 'const', so I am not allowed to
manipulate the elements directly. Do note that I do *not*
manipulate the histbin::bin element, which is used as the
key for sorting, and thus it ought to be safe to manipulate
the histbin::count elements.
std::set maintains its elements in sorted order; if the
elements were writable, you would be able to disrupt the
ordering that it relies on in its search/insert algorithms,
which would be a Very Bad Thing. Even though you know what
you are doing, and that it is safe, this cannot be guaranteed
in the general case, so the elements of std::set are defined
to be const. If you need modifiable data in a search tree,
there is a better data structure more suited to the task
(see below).
Is there a convemient, safe way to be able to use std::set
as the search tree for this histogram?
Not really, but read on...
If 'no', are there other STL containesr that can be used?
Your problem is best solved by utilising std::map instead
(it has the same complexity specifications as std::set).
std::map associates non-modifiable keys with modifiable
data elements. You can re-write your proto-code thus:
std::map<int, int> histogram;
while (/* data coming in */)
{
++histogram[bin];
}
As you can see, you no longer need your histbin structure,
as the data is distributed properly as a fixed key (your
histbin::bin) and mutable data (your histbin::count)
within each map element.
Note also that, in operator[], the map will create a new
element if the key is not already present, and
default-initialise its associated data (in this case,
set the "count" to zero), removing the need for your
original search-and-possibly-insert code.
Regards,
Tony.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]