Solved

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

Posted on 2007-11-19
10
753 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
  • 3
  • 3
  • 2
  • +2
10 Comments
 
LVL 55

Assisted Solution

by:Jaime Olivares
Jaime Olivares earned 220 total points
Comment Utility
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 220 total points
Comment Utility
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 220 total points
Comment Utility
Sorry, left some garbage, forget code starting with i=s.begin();
0
 
LVL 40

Assisted Solution

by:evilrix
evilrix earned 100 total points
Comment Utility
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 160 total points
Comment Utility
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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

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

Author Comment

by:Troudeloup
Comment Utility
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 20 total points
Comment Utility
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 160 total points
Comment Utility
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
Comment Utility
>>>> 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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

728 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now