473,657 Members | 2,661 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

finding an index in an STL vector<>

Joe
I have a: vector<string> which contains a few dozen elements.

I want to find the index of the element containing a certain string.

for example:

vector<string> strings;
strings.push_ba ck("abc");
strings.push_ba ck("xyz");
strings.push_ba ck("lmnop");

int index = distance(string s.begin(), find(strings.be gin(),
strings.end(), string("xyz"))) ;

cout << index << endl; // should print out a '1', the index of "xyz"

The above line using 'distance' seems pretty terrible to me. Please
tell me that there a better way?

Thanks in advance,
Joe
Jul 22 '05 #1
6 3772
"Joe" <jo********@gma il.com> wrote in message
news:60******** *************** ***@posting.goo gle.com...
I have a: vector<string> which contains a few dozen elements.

I want to find the index of the element containing a certain string.

for example:

vector<string> strings;
strings.push_ba ck("abc");
strings.push_ba ck("xyz");
strings.push_ba ck("lmnop");

int index = distance(string s.begin(), find(strings.be gin(),
strings.end(), string("xyz"))) ;

cout << index << endl; // should print out a '1', the index of "xyz"

The above line using 'distance' seems pretty terrible to me. Please
tell me that there a better way?


Ah, it's not that bad. The explicit construction of the std::string can be
eliminated to make it a little prettier, right? I can't think of anything
better offhand. If you think it's ugly, wrap it.

// optionally a template
std::size_t index_of_elemen t( std::vector<std ::string&>& vec, const
std::string& elem );

int index = index_of_elemen t( strings, "xyz" );

But why do you want the index when you already have an iterator?

--
David Hilsee
Jul 22 '05 #2
David Hilsee wrote:
"Joe" <jo********@gma il.com> wrote in message
news:60******** *************** ***@posting.goo gle.com...
I have a: vector<string> which contains a few dozen elements.

I want to find the index of the element containing a certain string.

for example:

vector<string > strings;
strings.push_ back("abc");
strings.push_ back("xyz");
strings.push_ back("lmnop");

int index = distance(string s.begin(), find(strings.be gin(),
strings.end() , string("xyz"))) ;

cout << index << endl; // should print out a '1', the index of "xyz"

The above line using 'distance' seems pretty terrible to me. Please
tell me that there a better way?

Ah, it's not that bad. The explicit construction of the std::string can be
eliminated to make it a little prettier, right? I can't think of anything
better offhand. If you think it's ugly, wrap it.

// optionally a template
std::size_t index_of_elemen t( std::vector<std ::string&>& vec, const
std::string& elem );

int index = index_of_elemen t( strings, "xyz" );

But why do you want the index when you already have an iterator?


Hi, this I'm the original poster 'Joe' just using a different new client...

Thanks for your quick response!

Why do I want an index when I already have an iterator?

Well, I had a class like this:

class foo {
[other class members]
string _bar;
public:
string bar() { return _bar; } // my reader function
bar([other parameters], bar) _bar(bar) {} // my constructor
}

The problem is that I have ten's of millions of objects instantiated
from this class, and I don't have enough RAM (and my machine can't hold
anymore than the 1GB it has).

So, since I know that there are only about 10 or 20 unique types of
'bar' I would just store them all in a static vector and store an index
(which only needs to be a char because there are only 10 or 20 unique
strings) to that vector in each object. So, I ended up with this:

class foo_new {
[ other class members]
static vector<string> mystrings;
char _bar_index; // this is just an index to the mystrings element
public:
string bar() { return mystrings[bar_index]; } // my reader function
foo_new([other parameters], string bar) { // constructor
int index = distance(string s.begin(), find(strings.be gin(),
strings.end(), bar));
if(index != strings.end()) {
_bar_index = index;
} else {
_bar_index = strings.size();
strings.push_ba ck(bar);
}
}
}

So, foo_new objects now have 'char bar_index' instead of 'string bar'
which will save me hundreds of megabytes.

If you can propose a better way of getting a similar result, I will be
both grateful and impressed.

-- Joe
Jul 22 '05 #3
"Joe Harris" <NO_SPAMjoe.har ris@KILL_ALL_SP AMMERSgmail.com > wrote in message
news:Xm******** **********@bign ews3.bellsouth. net...
<snip>
Hi, this I'm the original poster 'Joe' just using a different new client...
Thanks for your quick response!

Why do I want an index when I already have an iterator?

Well, I had a class like this:

class foo {
[other class members]
string _bar;
public:
string bar() { return _bar; } // my reader function
bar([other parameters], bar) _bar(bar) {} // my constructor
}

The problem is that I have ten's of millions of objects instantiated
from this class, and I don't have enough RAM (and my machine can't hold
anymore than the 1GB it has).

So, since I know that there are only about 10 or 20 unique types of
'bar' I would just store them all in a static vector and store an index
(which only needs to be a char because there are only 10 or 20 unique
strings) to that vector in each object. So, I ended up with this:

class foo_new {
[ other class members]
static vector<string> mystrings;
char _bar_index; // this is just an index to the mystrings element
public:
string bar() { return mystrings[bar_index]; } // my reader function
foo_new([other parameters], string bar) { // constructor
int index = distance(string s.begin(), find(strings.be gin(),
strings.end(), bar));
if(index != strings.end()) {
_bar_index = index;
} else {
_bar_index = strings.size();
strings.push_ba ck(bar);
}
}
}

So, foo_new objects now have 'char bar_index' instead of 'string bar'
which will save me hundreds of megabytes.

If you can propose a better way of getting a similar result, I will be
both grateful and impressed.


Well, I can't think of a better way to do what you're doing. It looks like
a flyweight. However, given that there are tens of millions of these
objects, I would probably verify a few things, if I were you. First, make
sure that there isn't a way you can reduce the number of elements. Can
these objects, or certain member of these objects, be computed on the fly?
Second, make sure that there aren't more members that can benefit from using
that static table. Third, make sure that you are realizing the benefits of
using a char instead of a std::vector<std ::string>::size _type and that your
code doesn't accidentally go beyond the range of a char. Other than that,
without knowing anything else, I'd say that the implementation looks pretty
solid.

If the call to distance still looks odd to you, you can use subtraction
instead, or separate it out into two different lines.

--
David Hilsee
Jul 22 '05 #4
In article <60************ **************@ posting.google. com>,
jo********@gmai l.com (Joe) wrote:
I have a: vector<string> which contains a few dozen elements.

I want to find the index of the element containing a certain string.

for example:

vector<string> strings;
strings.push_ba ck("abc");
strings.push_ba ck("xyz");
strings.push_ba ck("lmnop");

int index = distance(string s.begin(), find(strings.be gin(),
strings.end(), string("xyz"))) ;

cout << index << endl; // should print out a '1', the index of "xyz"

The above line using 'distance' seems pretty terrible to me. Please
tell me that there a better way?


That does look a little yuk. How about this?

// this is a bit ugly, but its use is much cleaner. See below
template < typename InputIterator, typename EqualityCompara ble >
typename iterator_traits <InputIterator> ::difference_ty pe
Index(const InputIterator& begin, const InputIterator& end,
const EqualityCompara ble& item) {
return distance(begin, find(begin, end, item));
}

int main() {
vector<string> strings;
strings.push_ba ck("abc");
strings.push_ba ck("xyz");
strings.push_ba ck("lmnop");

assert(Index(st rings.begin(), strings.end(), "xyz") == 1);
assert(Index(st rings.begin(), strings.end(), "WWW") ==
strings.size()) ; //line 1
assert(Index(st rings.rbegin(), strings.rend(), "lmnop") == 0);//line 2
cout << "OK";
}

Note how it handles error conditions (line 1.) Also note how it handles
reverse iterators (line 2)...
Jul 22 '05 #5
David Hilsee wrote:
"Joe Harris" <NO_SPAMjoe.har ris@KILL_ALL_SP AMMERSgmail.com > wrote in message
news:Xm******** **********@bign ews3.bellsouth. net...
<snip>
Hi, this I'm the original poster 'Joe' just using a different new


client...
Thanks for your quick response!

Why do I want an index when I already have an iterator?

Well, I had a class like this:

class foo {
[other class members]
string _bar;
public:
string bar() { return _bar; } // my reader function
bar([other parameters], bar) _bar(bar) {} // my constructor
}

The problem is that I have ten's of millions of objects instantiated
from this class, and I don't have enough RAM (and my machine can't hold
anymore than the 1GB it has).

So, since I know that there are only about 10 or 20 unique types of
'bar' I would just store them all in a static vector and store an index
(which only needs to be a char because there are only 10 or 20 unique
strings) to that vector in each object. So, I ended up with this:

class foo_new {
[ other class members]
static vector<string> mystrings;
char _bar_index; // this is just an index to the mystrings element
public:
string bar() { return mystrings[bar_index]; } // my reader function
foo_new([other parameters], string bar) { // constructor
int index = distance(string s.begin(), find(strings.be gin(),
strings.end() , bar));
if(index != strings.end()) {
_bar_index = index;
} else {
_bar_index = strings.size();
strings.push_ba ck(bar);
}
}
}

So, foo_new objects now have 'char bar_index' instead of 'string bar'
which will save me hundreds of megabytes.

If you can propose a better way of getting a similar result, I will be
both grateful and impressed.

Well, I can't think of a better way to do what you're doing. It looks like
a flyweight. However, given that there are tens of millions of these
objects, I would probably verify a few things, if I were you. First, make
sure that there isn't a way you can reduce the number of elements. Can
these objects, or certain member of these objects, be computed on the fly?
Second, make sure that there aren't more members that can benefit from using
that static table. Third, make sure that you are realizing the benefits of
using a char instead of a std::vector<std ::string>::size _type and that your
code doesn't accidentally go beyond the range of a char. Other than that,
without knowing anything else, I'd say that the implementation looks pretty
solid.

If the call to distance still looks odd to you, you can use subtraction
instead, or separate it out into two different lines.


I am now using subtraction and it looks better. I'm still getting up to
speed with STL and I wanted to make sure that what I was doing wasn't
too strange. It seemed odd to me that there was no more concise way to
express my thought, but I guess that -- as you say -- people usually are
happy with an iterator.

-- Joe
Jul 22 '05 #6
Daniel T. wrote:
In article <60************ **************@ posting.google. com>,
jo********@gmai l.com (Joe) wrote:

I have a: vector<string> which contains a few dozen elements.

I want to find the index of the element containing a certain string.

for example:

vector<string > strings;
strings.push_ back("abc");
strings.push_ back("xyz");
strings.push_ back("lmnop");

int index = distance(string s.begin(), find(strings.be gin(),
strings.end() , string("xyz"))) ;

cout << index << endl; // should print out a '1', the index of "xyz"

The above line using 'distance' seems pretty terrible to me. Please
tell me that there a better way?

That does look a little yuk. How about this?

// this is a bit ugly, but its use is much cleaner. See below
template < typename InputIterator, typename EqualityCompara ble >
typename iterator_traits <InputIterator> ::difference_ty pe
Index(const InputIterator& begin, const InputIterator& end,
const EqualityCompara ble& item) {
return distance(begin, find(begin, end, item));
}

int main() {
vector<string> strings;
strings.push_ba ck("abc");
strings.push_ba ck("xyz");
strings.push_ba ck("lmnop");

assert(Index(st rings.begin(), strings.end(), "xyz") == 1);
assert(Index(st rings.begin(), strings.end(), "WWW") ==
strings.size()) ; //line 1
assert(Index(st rings.rbegin(), strings.rend(), "lmnop") == 0);//line 2
cout << "OK";
}

Note how it handles error conditions (line 1.) Also note how it handles
reverse iterators (line 2)...


Interesting... thanks.
Jul 22 '05 #7

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

Similar topics

0
2260
by: Marc Schellens | last post by:
my dinkumware docu says, vector<...>::rbegin() returns an iterator which points just BEYOND the end of the controlled sequence. Is that true? so I cannot say: for( riter i=v.rbegin(); i != v.rend(); i++) { something = (*i); }
2
6743
by: john smith | last post by:
Hi, when there is a vector<> of pointers to some objects, does calling resize cause vector to call delete on each object, or is there a memory leak problem? for example: struct base {//some vars; ~base();}; vector<base*> vb; vb.push_back(new base); vb.push_back(new base);
10
7066
by: Stefan Höhne | last post by:
Hi, as I recon, std::vector::clear()'s semantics changed from MS VC++ 6.0 to MS' DOT.NET - compiler. In the 6.0 version the capacity() of the vector did not change with the call to clear(), in DOT.NET the capacity() is reduced to 0.
4
2338
by: Anu | last post by:
Hi, We have a class that has its own overloaded operator new and whose prototype seems to correspond to the standard placement new :- class AppClass { public: operator new (size_t size, void *ctx)
1
2346
by: OriginalCopy | last post by:
This is a demonstrative code which could be used for debugging purposes. And yet I don't know how to insert the necessary data on line 63, purely syntactically speaking ? I'm a beginner with STL, and from what I've read insert() accepts references for almost all of its overloaded versions. If so, what could one do so those element's memory space doesn't wipe out? I suppose one should use the heap. In rest I hope the code speaks for itself, it's...
5
1952
by: Numeromancer | last post by:
From the C++-FAQ Lite: http://www.parashift.com/c++-faq-lite/containers.html#faq-34.3 ---------------------------- 34.3] Is the storage for a std::vector<Tguaranteed to be contiguous? Yes. This means you the following technique is safe: #include <vector>
8
3608
by: jacek.dziedzic | last post by:
Hi! I need to be able to track memory usage in a medium-sized application I'm developing. The only significant (memory-wise) non- local objects are of two types -- std::vector<and of a custom class simple_vector<that is a hand-rolled substitute for array<>. With the latter I have code that tracks all allocations and destructions, so I can account for all the memory. The question is about std::vector<-- how can I track memory usage
3
5636
by: Rune Allnor | last post by:
Hi folks. I have a function that takes an element in a vector as argument. The naive interface goes as float computeSomething(const std::vector<float>& v, size_t i) { size_t j = i-1; size_t k = i+1;
1
2521
by: iammilind | last post by:
In one of my code, I was using vector<> for certain class. In one of my struct, I have 'const' member data. However, vector<>::clear() throws compile error with that: =========================================== struct Test { const string Str; Test(const string str) : Str(str) {} }; struct TestWrapper
0
8407
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8739
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...
0
8612
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7347
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...
1
6175
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4329
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2739
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1969
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1732
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.