473,791 Members | 3,122 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

why does STL binary-serach twice when deleting a set member?

JDT
Hi,

The last statement at the end of this post is to delete a set member
7.7. I set a break point inside ltstr::operator (). I found out that
STL binary-seach the set twice. How come? I have another problem that
a member in a set cannot be deleted. I think I may be able to solve
that problem if I can figure out the problem posted here. Thanks for
your help.

The sequence of (f1, f2) STL goes through is (7.7, 4.4), (7.7, 6.6),
(7.7, 8.8), (7.7, 7.7), (4.4, 7.7), (6.6, 7.7), (8.8, 7.7), and finally
(7.7, 7.7) again.
// *************** **************
struct ltstr // less than
{
bool operator()(cons t float f1, const float f2) const
{
return f1 f2;
}
};

int main(int argc, char* argv[])
{

set<float, ltstr s;
s.insert(1.1);
s.insert(2.2);
s.insert(3.3);
s.insert(4.4);
s.insert(5.5);
s.insert(6.6);
s.insert(7.7);
s.insert(8.8);
s.insert(9.9);

s.erase(7.7);
....

JD
Oct 19 '06 #1
8 1857
JDT <jd*******@yaho o.comwrote:
The last statement at the end of this post is to delete a set member
7.7. I set a break point inside ltstr::operator (). I found out that
STL binary-seach the set twice. How come?
This is probably just an implementation detail, but from what I
understand many implementations of std::set internall use some sort of
tree structure to keep the set sorted. When you delete a member, the
first search is probably to find the element to be deleted, and the
second may be some sort of rebalancing of the tree.
I have another problem that
a member in a set cannot be deleted. I think I may be able to solve
that problem if I can figure out the problem posted here. Thanks for
your help.
This problem may be a consequence of the fact that floating point
arithmetic is not exact; see

http://www.parashift.com/c++-faq-lit...html#faq-29.17

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Oct 19 '06 #2
JDT
Hi Marcus,

Thanks for the explanation. But an element cannot be deleted even after
I pay attention to your 2nd point. Basically I feed the following
customized less-than operator into a set. (I hope that the fTolerance
can be as small as possible) One in thousands of elements cannot be
deleted. I think the operator is only used for sorting/searching, but
not for the final matching. To match an element to be deleted at the
end of searching, pointers to CSetMember will be used for comparison.
Am I right? The operator shouldn't cause this type of problem as long
as it always returns a consistent bool value. It really puzzles me ....

struct lt
{
bool operator() (const CSetMember *s1, const CSetMember *s2) const
{
float f1 = s1->a * s1->b / s1->c;
float f2 = s2->a * s2->b / s2->c;
if (abs(f1-f2) fTolerance)
return f1 < f2;
else
return s1->id < s2->id; // id is a unique integer
}
};

JD
Marcus Kwok wrote:
JDT <jd*******@yaho o.comwrote:
>>The last statement at the end of this post is to delete a set member
7.7. I set a break point inside ltstr::operator (). I found out that
STL binary-seach the set twice. How come?


This is probably just an implementation detail, but from what I
understand many implementations of std::set internall use some sort of
tree structure to keep the set sorted. When you delete a member, the
first search is probably to find the element to be deleted, and the
second may be some sort of rebalancing of the tree.

> I have another problem that
a member in a set cannot be deleted. I think I may be able to solve
that problem if I can figure out the problem posted here. Thanks for
your help.


This problem may be a consequence of the fact that floating point
arithmetic is not exact; see

http://www.parashift.com/c++-faq-lit...html#faq-29.17
Oct 19 '06 #3
"JDT" <jd*******@yaho o.comwrote in message
news:jk******** **********@news svr13.news.prod igy.com...
Thanks for the explanation. But an element cannot be deleted even after I
pay attention to your 2nd point. Basically I feed the following
customized less-than operator into a set. (I hope that the fTolerance can
be as small as possible) One in thousands of elements cannot be deleted.
I think the operator is only used for sorting/searching, but not for the
final matching. To match an element to be deleted at the end of
searching, pointers to CSetMember will be used for comparison. Am I right?
The operator shouldn't cause this type of problem as long as it always
returns a consistent bool value. It really puzzles me ....

struct lt
{
bool operator() (const CSetMember *s1, const CSetMember *s2) const
{
float f1 = s1->a * s1->b / s1->c;
float f2 = s2->a * s2->b / s2->c;
if (abs(f1-f2) fTolerance)
return f1 < f2;
else
return s1->id < s2->id; // id is a unique integer
}
};
If this function ever returs true for both lt(s1, s2) and lt(s2, s1)
(and I strongly suspect it does) then it is *not* a strict weak
ordering, and set will not behave properly.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Oct 19 '06 #4
JDT
Hi P.J.,

Since I didn't change both s1's and s2's a, b, c, and id, the same
machine and same compile will always produce the same values of f1 and
f2. It's a strict weak ordering unless "(abs(f1-f2) fTolerance)"
produces different bools for lt(s1, s2) and lt(s2, s1). Is it possible?

JD
P.J. Plauger wrote:
"JDT" <jd*******@yaho o.comwrote in message
news:jk******** **********@news svr13.news.prod igy.com...

>>Thanks for the explanation. But an element cannot be deleted even after I
pay attention to your 2nd point. Basically I feed the following
customized less-than operator into a set. (I hope that the fTolerance can
be as small as possible) One in thousands of elements cannot be deleted.
I think the operator is only used for sorting/searching, but not for the
final matching. To match an element to be deleted at the end of
searching, pointers to CSetMember will be used for comparison. Am I right?
The operator shouldn't cause this type of problem as long as it always
returns a consistent bool value. It really puzzles me ....

struct lt
{
bool operator() (const CSetMember *s1, const CSetMember *s2) const
{
float f1 = s1->a * s1->b / s1->c;
float f2 = s2->a * s2->b / s2->c;
if (abs(f1-f2) fTolerance)
return f1 < f2;
else
return s1->id < s2->id; // id is a unique integer
}
};


If this function ever returs true for both lt(s1, s2) and lt(s2, s1)
(and I strongly suspect it does) then it is *not* a strict weak
ordering, and set will not behave properly.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com

Oct 19 '06 #5
"JDT" <jd*******@yaho o.comwrote in message
news:d5******** **********@news svr27.news.prod igy.net...
Hi P.J.,

Since I didn't change both s1's and s2's a, b, c, and id, the same machine
and same compile will always produce the same values of f1 and f2. It's a
strict weak ordering unless "(abs(f1-f2) fTolerance)" produces different
bools for lt(s1, s2) and lt(s2, s1). Is it possible?
A strict weak ordering unless... is not a strict weak ordering.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Oct 20 '06 #6
"JDT" <jd*******@yaho o.comwrote in message
news:d5******** **********@news svr27.news.prod igy.net...
Hi P.J.,

Since I didn't change both s1's and s2's a, b, c, and id, the same machine
and same compile will always produce the same values of f1 and f2. It's a
strict weak ordering unless "(abs(f1-f2) fTolerance)" produces different
bools for lt(s1, s2) and lt(s2, s1). Is it possible?
A strict weak ordering unless... is not a strict weak ordering.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com

Oct 20 '06 #7
Hello,

P.J. Plauger wrote:
"JDT" <jd*******@yaho o.comwrote in message
news:jk******** **********@news svr13.news.prod igy.com...
>Thanks for the explanation. But an element cannot be deleted even
after I
pay attention to your 2nd point. Basically I feed the following
customized less-than operator into a set. (I hope that the
fTolerance can
be as small as possible) One in thousands of elements cannot be
deleted. I think the operator is only used for sorting/searching, but
not for the
final matching. To match an element to be deleted at the end of
searching, pointers to CSetMember will be used for comparison. Am I
right? The operator shouldn't cause this type of problem as long as
it always
returns a consistent bool value. It really puzzles me ....

struct lt
{
bool operator() (const CSetMember *s1, const CSetMember *s2) const
{
float f1 = s1->a * s1->b / s1->c;
float f2 = s2->a * s2->b / s2->c;
if (abs(f1-f2) fTolerance)
return f1 < f2;
else
return s1->id < s2->id; // id is a unique integer
}
};

If this function ever returs true for both lt(s1, s2) and lt(s2, s1)
(and I strongly suspect it does) then it is *not* a strict weak
ordering, and set will not behave properly.
Even worse. It's not symmetry, that is causing the biggest problems with
that functor, but transitivity.

Take 3 objects of type CSetMember c1, c2, c3, where ->a and ->c are 1.0
and c1->b == 0.25*fTolerance c2->b == fTolerance c3->b ==
1.75*fTolerance . Then let c1->id==3, c2->id==2 and c3->id==1.

Then we have lt(c1,c2)==fals e, lt(c2,c1)== true, lt(c2,c3)==fals e,
lt(c3,c2)== true, so by transitivity lt(c3,c1) should be true, but
lt(c3,c1) == false and lt(c1,c3)==true . This cannot work in general.

If you want to study the effects of a wrong ordering functor on
std::set, you could for example check the order of the elements after
each insert or erase, but not only the neighbouring elements, try all
kinds of distances between the indexes.

Another problem above is using the absolute error to decide. This made
it really easy to find a counterexample. A better way to compare, if
floating point es involved, is comparing values rounded to the accuracy
the input suggests. Imagine a round(d,n) function rounding d to n
digits after decimal point.

// f1, f2 as above
float c1 = round(f1,4);
float c2 = rounf(f2,4);

if (c1 < c2) return true;
if (c1 == c2) return s1->id < s2->id;
return false;

The OP version cuts the range of numbers into pieces of length
fTolerance, but the points, where the pieces end are different with
every starting point. This must not happen. The discretization should
be uniform over all inputs. If you round your input in a sensible
manner, then you might be able to leave out the rounding inside.

Quite some years ago, I had problems with the qsort function of the
standard C library. It crashed, because it was optimized in a way that
a comparision function, not representing an order as required, would
make it including elements outside the array when sorting. A thrilling
experience.

Bernd Strieder

Oct 20 '06 #8
JDT wrote:
Hi,

The last statement at the end of this post is to delete a set member
7.7. I set a break point inside ltstr::operator (). I found out that
STL binary-seach the set twice. How come?
This is apparently not uncommon. Certain implementations will perform
an erase( key) by first calling lower_bound( key) and upper_bound( key),
and then removing the range of iterators returned by these two calls.
Seems wasteful, but typically set, multiset, map, and multimap are built
upon the same underlying framework, usually a red black tree. The range
search then works for all of these containers although it's less than
optimal for the non multi- versions.

FWIW, my version of gcc which seems to be based upon HP and SGI
implementations , does this. To get around this, you can perform a find
operation to return an iterator, and then erase the iterator directly.
If you feel like being fancy, you could even write a templatized
function to do this automatically-- cf. below.

Mark

// nb. untested code!

/* Erases element k, if present, from set s. Returns the number of
* erased elements (0 or 1).
*/
template< typename SetType, typename KeyType>
int setErase( SetType& s, const KeyType& k)
{
typename SetType::iterat or it = s.find( k);
if( it == s.end())
return 0;
s.erase( it);
return 1;
}
Oct 20 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
2041
by: Valentina | last post by:
What does this C++ line mean? bool bBoolean = (0!=(nInteger&0x08)); I don't understand the nInteger&0x08 bit. Thanks, Valentina
10
2923
by: Fredrik Celin | last post by:
I use IE 6.0 and does some calculations in a javascript. If I run this code: alert(1.4 - 0.5); i get the result 0.8999999999 and not 0.9 Does anybody know why? Is this a bug in IE or what? Any fast and easy ways to work around this problem?
2
2475
by: greatbooksclassics | last post by:
Open Source DRM? What does everyone think about it? Will Open Source DRM ever catch up to MS DRM? Will DRM ever be integrated into common LAMP applications? (LAMP=Linux/Apache/MYSQL/PHP/Perl/Python/Ruby) Here's Sun's latest initiative in Open Source DRM: DReaM: Royalty-Free, Open Source DRM
9
6520
by: Ching-Lung | last post by:
Hi all, I try to create a tool to check the delta (diff) of 2 binaries and create the delta binary. I use binary formatter (serialization) to create the delta binary. It works fine but the delta binary is pretty huge in size. I have 1 byte file and 2 bytes file, the delta should be 1 byte but somehow it turns out to be 249 bytes using binary formatter. I guess serialization has some other things added to the delta file.
1
2813
by: ATS | last post by:
PRB - HttpWebRequest does not work with CGI websites and/or RAW data Please help, I'm trying to make a web deploying UserControl that gets RAW binary data that is dynamically created from a CGI application webiste, and have the UserControl write the data down to a file. I've used the code listed here after to make this happen. If I plug in a URL to a non-CGI site, such as a static HTML page, the UserControl successfully get the output...
3
3347
by: Robin Tucker | last post by:
Does anyone have a VB.NET IPersistStream COM interface description I can cadge please? If I remember rightly, you have to "flatten" inherited COM interfaces (I think IPersistStream derives from IPersist or something). Thanks, Robin
29
3384
by: Vol | last post by:
I think 'atan' can get the angle but it is not the four quadrant angle. Is there any function that i can get the angle from -pi to pi? or I have to use some if ... else? I know in Matlab, we use 'atan2( )' Also, is there any function to get the round value, similar with floor and ceil, such like: round(3.1) = 3 round(3.6) = 4
9
5292
by: Someonekicked | last post by:
In my program, I need to open multiple files, and I wont know till after the program execution how many of them (user will enter that value). So I am using a vector of fstream. I am using fstream since I will need to write and read from files, and I am using those files as binary files. I made a sample of what's going on (below). Without using vector, everything works fine, but with using vectors, something is going wrong somewhere!?? ...
130
6642
by: Daniel Manes | last post by:
I'm baffled. I have a column in a SQL Server Express database called "Longitude," which is a float. When I view the table in a DataGridView, some of the numbers, which only have two decimal places in the database show up with *15* decimal places and are ever so slightly off (in the example in the subject line, by about 2E-15). I'm not doing any operations on this column. It's just running a stored procedure which performs a pretty basic...
9
2638
by: Ed Leafe | last post by:
On Apr 21, 2008, at 1:05 PM, Daniel Fetchinson wrote: Don't most binary distributions include SQLite itself? I installed 2.5.2 on a new WinXP VM, and SQLite is working fine. -- Ed Leafe
0
9512
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10419
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10201
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10147
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9023
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6770
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5424
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5552
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3709
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.