C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Why won't set<string> iterator work?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Steve Edwards
Guest





PostPosted: Sun Feb 26, 2006 12:34 pm    Post subject: Why won't set<string> iterator work? Reply with quote



Hi,

1)

I'm making a container for string pointers...

set<string*> strSet;

strSet.insert(...); // insert some strings
....
....


But when I come to iterate over them, I'm getting an error that there is
no operator= for iter:

set<string>::iterator iter;
for(iter = *strSet.begin(); iter != strSet.end(); iter++)

This is exactly what I did when I was learning about maps, and it worked
fine. Have I misunderstood, or should iterators work the same with all
containers?



2)
I could just as easily use a vector for these strings, and remove the
duplicates manually. However, when I tried this, nothing got removed,
even though I had no compiler errors:


vector<string> strVec;

strVec.push_back("test");
strVec.push_back("test");
strVec.push_back("test");

strVec[2].erase();

My text book states that vector is not ideal for random access removal,
but not that it is impossible. have I got this wrong?




Thanks

Steve
Back to top
Alf P. Steinbach
Guest





PostPosted: Sun Feb 26, 2006 1:06 pm    Post subject: Re: Why won't set<string> iterator work? Reply with quote



* Steve Edwards:
Quote:
1)

I'm making a container for string pointers...

set<string*> strSet;

strSet.insert(...); // insert some strings
...
...


But when I come to iterate over them, I'm getting an error that there is
no operator= for iter:

set<string>::iterator iter;
for(iter = *strSet.begin(); iter != strSet.end(); iter++)

This is exactly what I did when I was learning about maps, and it worked
fine. Have I misunderstood, or should iterators work the same with all
containers?

What's that '*' in there?


Quote:
2)
I could just as easily use a vector for these strings, and remove the
duplicates manually. However, when I tried this, nothing got removed,
even though I had no compiler errors:


vector<string> strVec;

strVec.push_back("test");
strVec.push_back("test");
strVec.push_back("test");

strVec[2].erase();

My text book states that vector is not ideal for random access removal,
but not that it is impossible. have I got this wrong?

Both. I mean, both the textbook and you. Whether a vector is ideal for
random access removal depends on context and what's meant by removal.

However, the code you have shown calls 'erase' on one of the strings in
the vector, which changes that string but does not remove it from the
vector.

Calling 'erase' on the vector would effect a removal (in the most common
sense of the word), but in time linear in the size of the vector.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Back to top
Ivan Vecerina
Guest





PostPosted: Sun Feb 26, 2006 2:06 pm    Post subject: Re: Why won't set<string> iterator work? Reply with quote



"Steve Edwards" <gfx (AT) lineone (DOT) net> wrote in message
news:gfx-B3E7FE.12371326022006 (AT) news (DOT) btinternet.com...
[ 1) already answered ]
: 2)
: I could just as easily use a vector for these strings, and remove the
: duplicates manually. However, when I tried this, nothing got removed,
: even though I had no compiler errors:
:
:
: vector<string> strVec;
:
: strVec.push_back("test");
: strVec.push_back("test");
: strVec.push_back("test");
:
: strVec[2].erase();
[again, Alf already pointed out your mistake]

: My text book states that vector is not ideal for random access removal,
: but not that it is impossible. have I got this wrong?

Removal of duplicate entries can be relatively efficient if
you do it all in one go ( using <algorithm> ):
std::sort( strVec.begin(), strVec.end() );
strVec.erase( std::unique( strVec.begin(), strVec.end() )
, strVec.end()
);

In some circumstances, the performance characteristics of this
approach could compete with those of std::set.

Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Back to top
Kai-Uwe Bux
Guest





PostPosted: Sun Feb 26, 2006 2:06 pm    Post subject: Re: Why won't set<string> iterator work? Reply with quote

Steve Edwards wrote:

Quote:
Hi,

1)

I'm making a container for string pointers...

set<string*> strSet;

If possible, work with set<string> not set<string*>. Note that std::set<>
keeps its elements in a sorted order and uses that order to determine if a
new element is already in the set. For string object the order is done by
lexicographic comparison, which is very likely what you want. For object of
type string*, however, the comparison is done by comparing the *pointers*
not the pointees.

Quote:

strSet.insert(...); // insert some strings
...
...


But when I come to iterate over them, I'm getting an error that there is
no operator= for iter:

set<string>::iterator iter;

Now, what makes you think that set<string> and set<string*> are in any way
related?

Quote:
for(iter = *strSet.begin(); iter != strSet.end(); iter++)

Ask yourself what the expression *strSet.begin() will evaluate to.

Quote:
This is exactly what I did when I was learning about maps, and it worked
fine.

No, either it is not what you did back then, or it did not work (or both).

Quote:
Have I misunderstood, or should iterators work the same with all
containers?


Quote:
2)
I could just as easily use a vector for these strings, and remove the
duplicates manually. However, when I tried this, nothing got removed,
even though I had no compiler errors:


vector<string> strVec;

strVec.push_back("test");
strVec.push_back("test");
strVec.push_back("test");

strVec[2].erase();

My text book states that vector is not ideal for random access removal,
but not that it is impossible. have I got this wrong?

This does not call the erase() method for the object strVec but for the
string object in strVec[2]. This is *not* what you say you intended doing.


Best

Kai-Uwe Bux
Back to top
Steve Edwards
Guest





PostPosted: Sun Feb 26, 2006 3:45 pm    Post subject: Re: Why won't set<string> iterator work? Reply with quote

In article <46dmdlFamcukU1 (AT) individual (DOT) net>,
"Alf P. Steinbach" <alfps (AT) start (DOT) no> wrote:

Quote:
* Steve Edwards:
1)

I'm making a container for string pointers...

set<string*> strSet;

strSet.insert(...); // insert some strings
...
...


But when I come to iterate over them, I'm getting an error that there is
no operator= for iter:

set<string>::iterator iter;
for(iter = *strSet.begin(); iter != strSet.end(); iter++)

This is exactly what I did when I was learning about maps, and it worked
fine. Have I misunderstood, or should iterators work the same with all
containers?

What's that '*' in there?

Ah... thanks. I was originally using pointers in my sets and got
confused.(They are subsets of a very large array of strings and I wanted
to avoid the memory overhead of having copies, but as Kai said the
sorting benefits are worth it.)





Quote:


2)
I could just as easily use a vector for these strings, and remove the
duplicates manually. However, when I tried this, nothing got removed,
even though I had no compiler errors:


vector<string> strVec;

strVec.push_back("test");
strVec.push_back("test");
strVec.push_back("test");

strVec[2].erase();

My text book states that vector is not ideal for random access removal,
but not that it is impossible. have I got this wrong?

Both. I mean, both the textbook and you. Whether a vector is ideal for
random access removal depends on context and what's meant by removal.

However, the code you have shown calls 'erase' on one of the strings in
the vector, which changes that string but does not remove it from the
vector.

Calling 'erase' on the vector would effect a removal (in the most common
sense of the word), but in time linear in the size of the vector.

OK, I see what I was doing wrong, and from Ivan's example I can see how
to do it using <algorithm>. But is there a way to use erase() in the
trivial case where you want to remove a single known index? i.e.

vector<string> vec;

vec.push_back("zero");
vec.push_back("one");
vec.push_back("two");

vec.erase( [1] ); !!
Back to top
Steve Edwards
Guest





PostPosted: Sun Feb 26, 2006 3:50 pm    Post subject: Re: Why won't set<string> iterator work? Reply with quote

In article <dts9uq$il8$1 (AT) news (DOT) hispeed.ch>,
"Ivan Vecerina" <INVALID_use_webform (AT) ivan (DOT) vecerina.com> wrote:

Quote:
"Steve Edwards" <gfx (AT) lineone (DOT) net> wrote in message
news:gfx-B3E7FE.12371326022006 (AT) news (DOT) btinternet.com...
[ 1) already answered ]
: 2)
: I could just as easily use a vector for these strings, and remove the
: duplicates manually. However, when I tried this, nothing got removed,
: even though I had no compiler errors:
:
:
: vector<string> strVec;
:
: strVec.push_back("test");
: strVec.push_back("test");
: strVec.push_back("test");
:
: strVec[2].erase();
[again, Alf already pointed out your mistake]

: My text book states that vector is not ideal for random access removal,
: but not that it is impossible. have I got this wrong?

Removal of duplicate entries can be relatively efficient if
you do it all in one go ( using <algorithm> ):
std::sort( strVec.begin(), strVec.end() );
strVec.erase( std::unique( strVec.begin(), strVec.end() )
, strVec.end()
);

In some circumstances, the performance characteristics of this
approach could compete with those of std::set.

Ivan

Thanks for the code which is specific for my application.
However, I am finding it difficult to find examples (in books or on the
web) of trivial cases of dealing with specific indexing. The above kind
of method would be overkill if you know you just want to remove
strVec[7].
Back to top
Kai-Uwe Bux
Guest





PostPosted: Sun Feb 26, 2006 5:06 pm    Post subject: Re: Why won't set<string> iterator work? Reply with quote

Steve Edwards wrote:

[snip]
Quote:
OK, I see what I was doing wrong, and from Ivan's example I can see how
to do it using <algorithm>. But is there a way to use erase() in the
trivial case where you want to remove a single known index? i.e.

vector<string> vec;

vec.push_back("zero");
vec.push_back("one");
vec.push_back("two");

vec.erase( [1] ); !!

From memory (not tested):

vec.erase( vec.begin() + 1 );


Best

Kai-Uwe Bux
Back to top
Steve Edwards
Guest





PostPosted: Sun Feb 26, 2006 6:09 pm    Post subject: Re: Why won't set<string> iterator work? Reply with quote

In article <dtsmn4$2c8$1 (AT) murdoch (DOT) acc.Virginia.EDU>,
Kai-Uwe Bux <jkherciueh (AT) gmx (DOT) net> wrote:

Quote:
Steve Edwards wrote:

[snip]
OK, I see what I was doing wrong, and from Ivan's example I can see how
to do it using <algorithm>. But is there a way to use erase() in the
trivial case where you want to remove a single known index? i.e.

vector<string> vec;

vec.push_back("zero");
vec.push_back("one");
vec.push_back("two");

vec.erase( [1] ); !!

From memory (not tested):

vec.erase( vec.begin() + 1 );


Best

Kai-Uwe Bux

Thanks, that appears to work as needed.

Steve
Back to top
Guest






PostPosted: Mon Feb 27, 2006 11:06 am    Post subject: Re: Why won't set<string> iterator work? Reply with quote

Steve Edwards wrote:
Quote:
In article <dts9uq$il8$1 (AT) news (DOT) hispeed.ch>,
"Ivan Vecerina" <INVALID_use_webform (AT) ivan (DOT) vecerina.com> wrote:

std::sort( strVec.begin(), strVec.end() );
strVec.erase( std::unique( strVec.begin(), strVec.end() )
, strVec.end()
);
Thanks for the code which is specific for my application.
However, I am finding it difficult to find examples (in books or on the
web) of trivial cases of dealing with specific indexing. The above kind
of method would be overkill if you know you just want to remove
strVec[7].

Yep. In that case, a solution might be
std::swap(strVec[7], strVec.back());
strVec.pop_back();
which is O(1) but of course destroys the order.

HTH,
Michiel Salters
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.