0

I am using Codeblocks-13.12 and language C++. I wanted to compare two consecutive elements of a set using iterator. But the compiler gave error. I tried that just as a guess because I didn't get any info to do this by enough googling. If it is possible to do, then it would be too great.

The problem statement that I am working on is simple. I have given an array. I have to print a single integer,the maximum number of elements such that the absolute difference between any two of the integers is <= 1. The answer must be >=2.

I have solved this problem 100% correctly using array and set. Comparing two values of set, which I couldn't do using set, I have done that part using array. But if this part could be done using the std::set, then it would be too amazing and advantageous. My code using both set and array is -

#include <bits/stdc++.h>
#define for0(i,n)          for(int i=0;i<n;i++)
#define inf                100000000
using namespace std;
int a[103];
map<int,int> mp;
set<int> st;
set<int>::iterator it;

int main()
{
    int n,maxi=-inf,x;
    scanf("%d",&n);
    for0(i,n) {scanf("%d",&a[i]);mp[a[i]]++;st.insert(a[i]);}
    if(sz(st)==1){ pf("%d\n",mp[a[0]]);return 0;}
    for (it=st.begin(); it!=st.end(); ++it)
    {
        if(mp[*it]>1) 
        {
            x=mp[*it];
            if(x>maxi) maxi=x;
        }
    }
    sort(a,a+n);
    for(int i=0;i<n-1;i++)
    {
        if(a[i]!=a[i+1] && a[i+1]-a[i]==1)
        {
            int x=mp[a[i]]+mp[a[i+1]];
            if(x>maxi) maxi=x;
        }
    }
    if(maxi==-inf) printf("0\n");
    else  printf("%d\n",maxi);
    return 0;
}

This code is the 100% correct solution. But I wished to do the array part using set- that is comparing two consecutive element. My tried code is -

#include <bits/stdc++.h>
#define for0(i,n)          for(int i=0;i<n;i++)
#define inf                100000000
using namespace std;
int a[103];
map<int,int> mp;
set<int> st;
set<int>::iterator it;

int main()
{
    int n,maxi=-inf,x;
    scanf("%d",&n);
    for0(i,n) {scanf("%d",&a[i]);mp[a[i]]++;st.insert(a[i]);}
    if(sz(st)==1){ pf("%d\n",mp[a[0]]);return 0;}
    for (it=st.begin(); it!=st.end(); ++it)
    {
        if(mp[*it]>1) 
        {
            x=mp[*it];
            if(x>maxi) maxi=x;
        }
        if(it + 1 != st.end() && *(it + 1)-*it==1) 
        { 
            x=mp[*it]+mp[*(it + 1)]; 
            if(x>maxi) maxi=x; 
        } 
    }
    if(maxi==-inf) printf("0\n");
    else  printf("%d\n",maxi);
    return 0;
}

All the code is same as above except I added inside the "for" loop of set-

if(it + 1 != st.end() && *(it + 1)-*it==1) 
{ 
    x=mp[*it]+mp[*(it + 1)]; 
    if(x>maxi) maxi=x; 
}

instead of the array part -

sort(a,a+n);
for(int i=0;i<n-1;i++)
{
    if(a[i]!=a[i+1] && a[i+1]-a[i]==1)
    {
        int x=mp[a[i]]+mp[a[i+1]];
        if(x>maxi) maxi=x;
    }
}

In the line consisting of " if(it + 1 != st.end() && *(it + 1)-*it==1) " - here I am getting the error - "no match for operator+ in 'it + 1' ". So, this way is not correct. But I want to know that is there any way to do the described operation that I am trying to do using set? Please if anyone can help, it would be great.

amp1590
  • 43
  • 8
  • It's unreadable. http://format.krzaq.cc/. Don't use MACRO like that... – Stargateur Dec 13 '16 at 18:25
  • Your use of iterators is invalid, and would not even compile. Use `*it` to access the element corresponding to the iterator `it`, not `mp[*it]`. – Peter Dec 13 '16 at 18:28
  • This looks very strange: `if(mp[*it]>1) x=mp[*it]; { if(x>maxi) maxi=x; }` – πάντα ῥεῖ Dec 13 '16 at 18:30
  • 1
    Off topic: [Why should I not #include ?](http://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) and [Why is “using namespace std” considered bad practice?](http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). Putting the two together is a really bad idea. – user4581301 Dec 13 '16 at 18:31
  • @Peter: If you look at the types of `mp` and `it`, the expression `mp[*it]` makes perfect sense. – Benjamin Lindley Dec 13 '16 at 18:44
  • @Peter: It's correct and logically works. – amp1590 Dec 13 '16 at 19:12
  • @πάντα ῥεῖ : It's logical because actually in this line I am checking whether the set element indexed in the map mp is present how many times in the input array a[103]. And if so, then I am giving my required next steps. – amp1590 Dec 13 '16 at 19:15
  • @ user4581301 : Thanks for the info. I didn't know these two thing. Thanks. – amp1590 Dec 13 '16 at 19:16
  • @amp1590 But why using an extra scope block for `{ if(x>maxi) maxi=x; }`?? Can you elaborate why you did so please? Shouldn't that be `if(mp[*it]>1) { x=mp[*it]; if(x>maxi) maxi=x; }`? – πάντα ῥεῖ Dec 13 '16 at 19:20
  • @πάντα ῥεῖ : I am so sorry. I don't know how and when I did that !! It just totally make no sense !! It's a totally unintentional mistake. May be it occured while typing the question. Sorry for the interruption. I am editing it. – amp1590 Dec 13 '16 at 19:29

1 Answers1

2

Your problem in reduced form:

set<int> st;
set<int>::iterator it;
for (it=st.begin(); it!=st.end(); ++it)
{
    if(it + 1 != st.end() && *(it + 1)-*it==1) {  // << error
    //do something
    }
}

The compiler error no match for operator+ in 'it + 1' is self-explanatory. Instead you should use next:

if(next(it) != st.end() && *(next(it))-*it==1) 
Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
  • Thank you so much. I didn't have totally any idea about "next". @Saurav – amp1590 Dec 13 '16 at 19:08
  • 1
    @amp1590 `std::set` and `std::map` provides bidirectional iterator. You can do `it + n` only for random access iterator. – Slava Dec 13 '16 at 19:13