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 

searching a deque of deques using find_if

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
benbowc@attglobal.net
Guest





PostPosted: Thu Sep 15, 2005 10:18 am    Post subject: searching a deque of deques using find_if Reply with quote



I was attempting to use the find_if algorithm in my deque of deques to
search for a matching string but I can't seem to figure out how one
does
this?
The terse documentation appears to indicate I should create a
binary function to do the comparison and have it return TRUE for a
match. I can't figure out how to do this. Has anyone got a piece of
code that uses a container class in this manner?
I have got a deque of deques containing structures that contain unique
names. I want to add additional, filled, structures based on the name
string to an existing deque or add a new one when theres no match. If
anyone has a better
solution I'm more than willing to hear it too!

TIA

Craig


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
msalters
Guest





PostPosted: Thu Sep 15, 2005 1:57 pm    Post subject: Re: searching a deque of deques using find_if Reply with quote




benb... (AT) attglobal (DOT) net schreef:

Quote:
I was attempting to use the find_if algorithm in my deque of deques to
search for a matching string but I can't seem to figure out how one
does
this?
The terse documentation appears to indicate I should create a
binary function to do the comparison and have it return TRUE for a
match. I can't figure out how to do this. Has anyone got a piece of
code that uses a container class in this manner?

The problem isn't really in the predicate(which is unary, not binary).
find_if finds an element in a linear range [begin,end). You don't have
iterators for such a range. Your strings are 2D, not 1D.

A "simple" solution is to define an iterator that loops over all
strings, continuing with deque[1].begin after deque[0].end
IIRC, such code is publicly available as part of the VTL.
( check out concatenation_view< > )

HTH,
Michiel Salters


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
John Potter
Guest





PostPosted: Thu Sep 15, 2005 1:58 pm    Post subject: Re: searching a deque of deques using find_if Reply with quote



On 15 Sep 2005 06:18:46 -0400, [email]benbowc (AT) attglobal (DOT) net[/email] wrote:

Quote:
I was attempting to use the find_if algorithm in my deque of deques to
search for a matching string but I can't seem to figure out how one
does this?

I have got a deque of deques containing structures that contain unique
names. I want to add additional, filled, structures based on the name
string to an existing deque or add a new one when theres no match. If
anyone has a better solution I'm more than willing to hear it too!

If I understand you, each deque has Things with matching name fields.
Different names go in different deques. You have a Thing and wish to
add it to the deque for matching names or add a new deque for that
name. There will unconditionally be one more Thing in the collection.

struct Thing {
string name;
// ...
};

You wish to use find_if.

struct EqualThingName {
string const& name;
EqualThingName (string const& name) : name(name) {
}
bool operator() (deque<Thing> const& lhs) {
return lhs[0].name == name;
}
};
void addToCollection (deque<deque& ddt, Thing const& t) {
deque<deque::iterator it(find_if(ddt.begin(),
ddt.end(), EqualThingName(t.name)));
if (it != ddt.end())
it->push_back(t);
else
ddt.push_back(deque<Thing>(1, t));
}

You could also use find.

bool operator== (deque<Thing> const& lhs, string const& rhs) {
return lhs[0].name == rhs;
}
void addToCollection (deque<deque& ddt, Thing const& t) {
deque<deque::iterator it(find(ddt.begin(),
ddt.end(), t.name));
if (it != ddt.end())
it->push_back(t);
else
ddt.push_back(deque<Thing>(1, t));
}

Or, you could use the string as the key in a map and let it do
the work for you.

void addToCollection (map<string, deque& mdt,
Thing const& t) {
mdt[t.name].push_back(t);
}

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
benbowc@attglobal.net
Guest





PostPosted: Fri Sep 16, 2005 1:25 pm    Post subject: Re: searching a deque of deques using find_if Reply with quote

John Potter wrote:
Quote:
On 15 Sep 2005 06:18:46 -0400, [email]benbowc (AT) attglobal (DOT) net[/email] wrote:


I was attempting to use the find_if algorithm in my deque of deques to
search for a matching string but I can't seem to figure out how one
does this?


I have got a deque of deques containing structures that contain unique
names. I want to add additional, filled, structures based on the name
string to an existing deque or add a new one when theres no match. If
anyone has a better solution I'm more than willing to hear it too!


If I understand you, each deque has Things with matching name fields.
Different names go in different deques. You have a Thing and wish to
add it to the deque for matching names or add a new deque for that
name. There will unconditionally be one more Thing in the collection.

Thats correct.
Quote:

struct Thing {
string name;
// ...
};

You wish to use find_if.

struct EqualThingName {
string const& name;
EqualThingName (string const& name) : name(name) {
}
bool operator() (deque<Thing> const& lhs) {
return lhs[0].name == name;
}
};
void addToCollection (deque<deque& ddt, Thing const& t) {
deque<deque::iterator it(find_if(ddt.begin(),
ddt.end(), EqualThingName(t.name)));
if (it != ddt.end())
it->push_back(t);
else
ddt.push_back(deque<Thing>(1, t));
}

Boy I need to take some time to mull this over.


Quote:
You could also use find.

bool operator== (deque<Thing> const& lhs, string const& rhs) {
return lhs[0].name == rhs;
}
void addToCollection (deque<deque& ddt, Thing const& t) {
deque<deque::iterator it(find(ddt.begin(),
ddt.end(), t.name));
if (it != ddt.end())
it->push_back(t);
else
ddt.push_back(deque<Thing>(1, t));
}

Bit confused here. Whats the operator for? You don't use it do you?


Quote:
Or, you could use the string as the key in a map and let it do
the work for you.

void addToCollection (map<string, deque& mdt,
Thing const& t) {
mdt[t.name].push_back(t);
}

Now this is very tidy. I'll have to spend some time working through

this and its implications. I had considered a map but wondered about
random access. Is it quick?
The application code may access any member of the container at anytime
in any order. Will this work?
Thanks for the wonderful suggestions. Your skills are well beyond mine
at present.

Craig


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Greg Herlihy
Guest





PostPosted: Sun Sep 18, 2005 12:05 pm    Post subject: Re: searching a deque of deques using find_if Reply with quote

msalters wrote:
Quote:
benb... (AT) attglobal (DOT) net schreef:

I was attempting to use the find_if algorithm in my deque of deques to
search for a matching string but I can't seem to figure out how one
does
this?
The terse documentation appears to indicate I should create a
binary function to do the comparison and have it return TRUE for a
match. I can't figure out how to do this. Has anyone got a piece of
code that uses a container class in this manner?

The problem isn't really in the predicate(which is unary, not binary).
find_if finds an element in a linear range [begin,end). You don't have
iterators for such a range. Your strings are 2D, not 1D.

A "simple" solution is to define an iterator that loops over all
strings, continuing with deque[1].begin after deque[0].end
IIRC, such code is publicly available as part of the VTL.
( check out concatenation_view< > )

HTH,
Michiel Salters

For the purposes of this search the data is linear - only the first
element in each deque needs to be checked for a match. Using an
iterator that loops through all the items in all the containers would
make an already inefficient design, an order of magnitude slower still.

Replacing the deque of deques with a map of deques (or vectors) seems
like an obvious improvement. Consider the case in which a new container
must be created. With 64 containers, a linear search through the deque
will have to make 64 comparisons before it decides to create a new one.
A binary search through a std::map would need only 6 comparisons (log2
64) to reach the same conclusion. With 1024 containers, the difference
is 1024 vs. 10 comparisons, a hundredfold difference. At some point the
data set may become large enough that these ratios will make a
difference.

Greg


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
John Potter
Guest





PostPosted: Sun Sep 18, 2005 1:34 pm    Post subject: Re: searching a deque of deques using find_if Reply with quote

On 16 Sep 2005 09:25:00 -0400, [email]benbowc (AT) attglobal (DOT) net[/email] wrote:

Quote:
John Potter wrote:

struct Thing {
string name;
// ...
};

You could also use find.

bool operator== (deque<Thing> const& lhs, string const& rhs) {
return lhs[0].name == rhs;
}
void addToCollection (deque<deque& ddt, Thing const& t) {
deque<deque::iterator it(find(ddt.begin(),
ddt.end(), t.name));
if (it != ddt.end())
it->push_back(t);
else
ddt.push_back(deque<Thing>(1, t));
}

Bit confused here. Whats the operator for? You don't use it do you?

Find is basicly

while (first != past && ! (*first == target))
++ first;

It needs the above operator== for deque and string.

Quote:
Or, you could use the string as the key in a map and let it do
the work for you.

void addToCollection (map<string, deque& mdt,
Thing const& t) {
mdt[t.name].push_back(t);
}

Now this is very tidy. I'll have to spend some time working through
this and its implications. I had considered a map but wondered about
random access. Is it quick?

Looking only at the part you specified, addToCollection, the first two
use linear, O(N), searches while map uses binary, O(lgN), search.

Quote:
The application code may access any member of the container at anytime
in any order. Will this work?

You are asking for a compare between ddt[4][2] which is O(1) and
mdt[name][2] which is O(lgN). How do you translate between name
and 4? How would the application decide to access ddt[4] with no
knowledge of the name used in that collection? If that also
requires a search for the right deque, the map wins hands down.
I also wonder how the application decided on the 2. There is
nothing to prevent duplicates in the inner deques. Maybe it should
really be a map<string, map. Insufficient data
to answer question.

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) 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.