Access Set Elements by Index in C++

In this article we will discuss how to access an element by index in a Set.

std::set is an associative container, which internally store elements in a balanced binary search tree and it doesn’t provide random access operator [].

Therefore accessing a random element from set by index is little tricky.

Accessing nth element in Set

Suppose we have a set of strings i.e.

std::set<std::string> setOfStr =
            { "bb", "ee", "dd", "aa", "ll" };

Inside the set elements will be stores in sorted order i.e.

aa
bb
dd
ee
ll

Now, to access an element at nth index we need to create an iterator pointing to starting position and keep on  increment the iterator till nth element is reached i.e.



    std::set<std::string>::iterator setIt = setOfStr.begin();
    for(int i = 0; i < 3; i++)
    	setIt++;
    
    std::cout<<"3rd Element in set = "<<*setIt<<std::endl;

    But you don’t need to write this code again and again. STL provides two algorithms which serves the same purpose.

    Accessing nth element using std::advance

    template< class InputIt, class Distance >
    void advance( InputIt& it, Distance n );

    std::advance accepts an iterator and  a value by which it  advances the given iterator.  Let’s see how to access 3rd element using std::advance

    // Iterator to the beginning of set
    std::set<std::string>::iterator iter = setOfStr.begin();
    
    // It will move forward the passed iterator by passed value
    std::advance(iter, 3);
    
    std::cout<<"3rd Element in set = "<<*iter<<std::endl;

     

    Accessing nth element using std::next

    template <class ForwardIterator>
    ForwardIterator next (ForwardIterator it,
    typename iterator_traits<ForwardIterator>::difference_type n = 1);

    It is introduced in c++11, unlike std::advance it doesn’t increment the given iterator, instead it returns a new iterator that will be n position advanced to given iterator.
    Let’s see how to access the 3rd element using std::next,

    // std::next internally iterate through n elements to reach
    // nth element and returns the iterator of 3rd element in the set
    std::set<std::string>::iterator it = std::next(setOfStr.begin(), 3);
    
    std::cout<<"3rd Element in set = "<<*it<<std::endl;

    In all the above methods we need to check if n < size of set before calling std::next or std::advance i.e.

    // Checking of size is must
    if(setOfStr.size() > 3)
    {
    	std::set<std::string>::iterator it = std::next(setOfStr.begin(), 3);
    	std::cout<<"3rd Element in set = "<<*it<<std::endl;
    }

     

    Creating generic method to access nth element from any set

    Let’s create a generic method that will return the nth element and will also check for errorneous scenarios i.e. what if n > size i.e.

    Complete example is as follows,

    #include <iostream>
    #include <set>
    #include <string>
    #include <algorithm>
    
    
    /*
     * Access nth element from a set.
     * It returns a pair of Element and bool.
     * bool represents if nth element exists in set or not.
     * if bool is true them First element of pair T contains the element value
     */
    template <typename T>
    std::pair<T, bool> getNthElement(std::set<T> & searchSet, int n)
    {
    	std::pair<T, bool> result;
    	if(searchSet.size() > n )
    	{
    		result.first = *(std::next(searchSet.begin(), n));
    		result.second = true;
    	}
    	else
    		result.second = false;
    
    	return result;
    }
    
    int main()
    {
    	std::set<std::string> setOfStr =
    				{ "bb", "ee", "dd", "aa", "ll" };
    
    	std::cout<<"***** Set Contents *****"<<std::endl;
    	for(std::string elem : setOfStr)
    		std::cout<<elem<<std::endl;
    
    	std::cout<<"***** Accessing Elements by Index ***"<<std::endl;
    
    	// Access 3rd element
    	std::pair<std::string, bool> result = getNthElement(setOfStr, 3);
    
    	if(result.second)
    		std::cout<<"3rd Element in set = "<<result.first<<std::endl;
    	else
    		std::cout<<"3rd Element in set not found"<<std::endl;
    
    
    	// Access 7th element
    	result = getNthElement(setOfStr, 7);
    
    	if(result.second)
    		std::cout<<"7th Element in set = "<<result.first<<std::endl;
    	else
    		std::cout<<"7th Element in set not found"<<std::endl;
    
    }
    

    Output:

    ***** Set Contents *****
    aa
    bb
    dd
    ee
    ll
    ***** Accessing Elements by Index ***
    3rd Element in set = ee
    7th Element in set not found

     

     

    Scroll to Top