3

How can I directly access a element of a STL set by index??

I got errors no match for 'operator+'

#include<bits/stdc++.h>
..
set < long  long > s;
set <long long > :: iterator it;
it = s.begin() + k;
       cout << (*it);

here k is the index of require element.

fore more specifically i want to solve a problem using set.

here is the problem link: k-th divisor

and this is my error code:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    set<long long> s;
    set<long long >:: iterator it;
    long long i,n,k, ln;
    cin >> n>> k;
        ln = sqrt(n);
        for(i = 1; i <= ln; i++)
        {
            if(n%i == 0)
            {
                s.insert(i);
                s.insert(n/i);
            }
        }
        if(s.size() < k)
            printf("-1\n");
        else
        {
            it = s.begin() + k;
            cout << (*it);
        }

        s.clear();
    return 0;
}

help me out

3 Answers3

5

For this expression to work:

s.begin() + k;

Iterator must satisfy the RandomAccessIterator concept. As stated in the std::set documentation its iterator is BidirectionalIterator, so you cannot add an offset to it. What you can use is std::next():

it = std::next( s.begin(), k );

but you need to be aware this will increase the iterator k times. Or you can change your container to one which provides a random access iterator (for example std::vector).

jaggedSpire
  • 4,423
  • 2
  • 26
  • 52
Slava
  • 43,454
  • 1
  • 47
  • 90
  • it's not working.i got **it's a not member of 'std'** – Mohibur Rahman Jun 30 '17 at 13:33
  • @MohiburRahman you should start reading documentation rather than expect babysitting all the time. Click on link for `std::next` documentation and there is information there which header needs to be included. If you use old compiler that does not support C++11 you can use `std::advance` or simple loop, but better switch to better compiler. There are many which are free to use. – Slava Jun 30 '17 at 13:34
  • Thanks a lot-- @Slava – Mohibur Rahman Jun 30 '17 at 13:46
4

std::set has Bidirectional Iterators. They are not random access iterators, so you cannot directly skip ahead arbitrary number of elements. If you want the Nth element from a given iterator (from begin in this case) you must advance the iterator that many times. Fortunately, there is the std::advance function which will do it for you.

Try

it = s.begin();
std::advance(it, k);
François Andrieux
  • 28,148
  • 6
  • 56
  • 87
3

You want std::next:

it = std::next(s.begin(), k);

But note that as index increases, it gets more and more slow. If possible, you should try different approach.


Perhaps you're trying to iterate over a set?

Then you should use

for (long long it : s)
    std::cout << it;

or

for (auto it = s.begin(); it != s.end(); it++)
    std::cout << *it;
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207