?
Solved

[noob][c++] how do I access set element?

Posted on 2007-11-19
10
Medium Priority
?
759 Views
Last Modified: 2010-04-01
#include <iostream>
#include <set>

using namespace std;

int main()
{
      set <int, greater<int> > s;
      set <int, greater<int> > ::iterator i;
      
      s.insert ( 4 );
      s.insert ( 5 );      
      
       cout << "The set contains the elements: " << endl;
      for (i=s.begin();  i !=s.end();  i++)
      {
            cout << *i  << endl;
      }
      
      i = s.begin();
      
        // can I cout an element of the set?
      cout << s.i << endl;
            
      
      
      
      return 0;
}
0
Comment
Question by:Troudeloup
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2
  • +2
10 Comments
 
LVL 55

Assisted Solution

by:Jaime Olivares
Jaime Olivares earned 880 total points
ID: 20314327
As explained in other questions, you gain access to each set element by traversing the set, just like this:
for (i=s.begin();  i !=s.end();  i++)
      {
            cout << *i  << endl;
      }

if you want access an element by index, you have to traverse anyway. something like this:

int GetSetElementByIndex( set <int, greater<int> > &s, index)
{
      set <int, greater<int> > ::iterator i;
 
      int idx= 0;
      for (i=s.begin();  i !=s.end();  i++, idx++)
      {
            if (idx==index)
                 return *i;
      }
      return 0;
}
     
0
 
LVL 55

Assisted Solution

by:Jaime Olivares
Jaime Olivares earned 880 total points
ID: 20314343
So you can use as:

#include <iostream>
#include <set>

using namespace std;

int main()
{
      set <int, greater<int> > s;
     
      s.insert ( 4 );
      s.insert ( 5 );      
      s.insert ( 7 );      
      s.insert ( 5 );      // again
      s.insert ( 12 );      
     
       cout << "The 3rd element in set contains is: " << endl;
       cout << GetSetElementByIndex(s, 3)  << endl;
}
     
      i = s.begin();
     
        // can I cout an element of the set?
      cout << s.i << endl;
           
     
     
     
      return 0;
}
0
 
LVL 55

Assisted Solution

by:Jaime Olivares
Jaime Olivares earned 880 total points
ID: 20314351
Sorry, left some garbage, forget code starting with i=s.begin();
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 40

Assisted Solution

by:evilrix
evilrix earned 400 total points
ID: 20314458
Below is an example that shows two different ways to traverse a set and gain access to the elements within.

I hope this helps.

-Rx.
#include <set>
#include <algorithm>
#include <iostream>
 
void OutputInt(int n)
{
	std::cout << n << std::endl;
}
 
int main()
{
	// Create typedef to make code cleaner
	typedef std::set<int> IntSet;
 
	// Create instance of int set
	IntSet intSet;
 
	// Populate int set
	for(int i = 0 ; i < 100 ; ++i)
	{
		intSet.insert(i);
	}
 
	// Traverse using for loop
	std::cout << "Traverse set using normal C++ for loop and output contents" << std::endl;
	for(IntSet::const_iterator itr = intSet.begin() ; itr != intSet.end() ; ++ itr)
	{
		// You need to dereference itr to get reference to type it represents
		// Iterators have pointer semantics
		OutputInt(*itr);
	}
 
	// Traverse set using STL for_each
	std::cout << "Traverse set using STL for_each and output contents" << std::endl;
	std::for_each(intSet.begin(), intSet.end(), OutputInt);
 
	return 0;
}

Open in new window

0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 640 total points
ID: 20314717
The answer to that question already was given in more than thread, e. g. in last comment of http:Q_22966252.html.

You shouldn't accept solutions if your questions are not answered. It is frustrating for an expert if an already answered question comes again and there was not a single hint why the previously made comments did not sufficently answered the question.

Regards, Alex
 

0
 

Author Comment

by:Troudeloup
ID: 20314781
yes, i am working on my problem solving ability, especially communications with experts.
0
 

Author Comment

by:Troudeloup
ID: 20314839
here is an odd thing



s.begin()

cout << i* << endl;

output 5.


i++;
cout << i* << endl;

output 4.


and then

i++  //aka s.end()

cout << i* << endl;

output would be 2.


why is there a 3rd element?
0
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 80 total points
ID: 20314882
First of all, it's *i, and not i*


>> why is there a 3rd element?

You shouldn't dereference an iterator that points to s.end() ...Don't output it either.
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 640 total points
ID: 20315112
Again, a std::set is a strange container. It is *not* a list and it is *not* an array. It isn't a dictionary either.

The differences to a list are:

- a set has unique items only, i. e. a set<int> cannot contain the item 5 twice.
- a set is ordered. The order depends on the comparision operator which defaults to the 'less' operator but can be any comparision function taking two const reference arguments of the type used as template type in set:
     
     bool comparefunction(const T& t1, const T& t2);  

Note, the compare function can be a template function but must not be a template function.

- like a list a set cannot be indexed. That is cause the elements in a set are not stored in an array (normally) but are linked (often in a binary tree) what makes it rather impossible to deduce a single item from an index beside of iterating the whole container.

The differences to a vector (array) are:

- the vector can be indexed.
- the set is always sorted, the vector can be sorted.
- the vector can have duplicate items:

   vector<int> v(100, 0);   // all 100 items have value 0

The differences to a map are

- the map has two template types a key type and a data type
- the set has only key type (or only data type if you like better).
- the map provides an 'indexed' access using the key for index. Differently to a 'normal' index the keys may have 'gaps' and may not be incrementable at all, e. g. a 'string' key.
- the set could have indexed access via key but that makes no sense as the 'data' to retrieve would be the key itself.
- set and map have a find function where you can retrieve an *iterator* to the item found or get the end() iterator which points beyond the container to indicate a non-existence.

All containers can be iterated using a iteration from begin() to end() and incrementing the iterator by using operator++. An iterator is a 'helper' class 'embedded' into the container class which stores 'pointers' to the current element of the container, where *current* is related to the iteration made with the iterator. So, with

    set<int>::iterator iter = myset.begin();

the class object 'iter' is a copy of the iterator returned by set::begin() and *points* to the first element (node) of the set container. That always is the lowest value (related to the used comparision). By ++iter (or iter++) the iter object now points to the next item of the container. If there is no next item, iter becomes equal to the iterator returned by myset.end().

>>>> how do I access set element?
You do access a set element by using an iterator. You can retrieve an iterator by the set::find, set::begin, set::end (and set::rbegin, set::rend) and by using increment or decrement operators. Note, using the iterator returned by set::find can be a non-trivial operation though of course the data found is the same as the key input. But you can 'update' the set element using the iterator what means that the old value was erased and the new value was inserted:

     set<int> myset;
     myset.insert(5);
     myset.insert(2);
     myset.insert(4);
     // that gives  2 4 5 in set

     set<int>::iterator iter = myset.find(2);
     *iter = 6;

     // now we have   4 5 6 in set.

The main purpose of a set container is to eliminate duplicates and to get a sorted collection. The purpose isn't to get an indexed collection.

Regards, Alex
               


0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20315164
>>>> You shouldn't dereference an iterator that points to s.end() ...Don't output it either.
It is a good chance that it crashes. If the set::end() iterator would have a NULL pointer to indicate the out-of-bounds, dereferencing would crash. You've been lucky that it seems to point to a real node element with an arbitrary data item.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

801 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question