user3512203
user3512203

Reputation: 73

C++ negative array indices

I want to loop an array then during each loop I want to loop backwards over the previous 5 elements.

So given this array

 int arr[24]={3, 1, 4, 1, 7, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2, 3, 8, 4, 6, 2, 6, 4}

and this nested loop

 for(int i=0;i<arr.size;i++)
 {
      for(int h=i-5; h<i; h++)
      {
        //things happen
      }
 }

So, if i=0, second loop would loop last few elements 4,6,2,6,5. How could you handle this?

Upvotes: 0

Views: 1167

Answers (6)

Baldrickk
Baldrickk

Reputation: 4409

I'm assuming that:

  • You only want to go over previous values (i.e. no wrap around) You
  • You don't actually want arr to be a multi-dimensional array as suggested by your choice of tags
  • You want to include the current i in your five values

This is just a small modification to your code that will do (what I think) you are asking:

#include <math>
int main()
{
   int arr[24]={3, 1, 4, 1, 7, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2, 3, 8, 4, 6, 2, 6, 4}

   for(int i=0;i<arr.size;i++)
   {
     for(int h = max(i-4, 0); h < i+1; h++)
     {
        //things happen
     }
   }
}

note the h = max(i-4, 0) and h < i+1This will reduce the number of iterations of the inner loop so that it starts from index 0 and loops up through the five values up to and including i. (four values and i). h will always be within bounds.
The case where i==arr.size won't be a problem in the inner loop as the outer loop will terminate before that happens (i is always within bounds).

Edit: I saw this comment:

I want the first element to consider the last final 5 elements of the array though.

in which case, your loops should look like:

 for(int i=0;i<arr.size;i++)
 {
      for(int h=0; h<5; h++)
      {
          int index = (i + arr.size - h) % arr.size;
          //things happen
          //access array with arr[index];
      }
 }

This should do what you want:

When i=0, h=0 index=(0+24-0)%24 which is 0. For h=1 we go one less, index=(0+24-1)%24 = 23 and so on for the next values of h.
The code gets the last 5 values, wrapping round, inclusive of the current value. (so will get 20,21,22,23,0 when i=0, 21,22,23,0,1 when i=1)

If you want the five before, non-inclusive, then inner loop should be:

for(int h=1; h<=5; h++)

here is the current output of the loop as it stands:

i     0  0  0  0  0  1  1  1  1  1  2  2  2  2  2  3  3  3  3  3 ... 22 22 22 22 22 23 23 23 23 23
h     0  1  2  3  4  0  1  2  3  4  0  1  2  3  4  0  1  2  3  4 ...  0  1  2  3  4  0  1  2  3  4
index 0 23 22 21 20  1  0 23 22 21  2  1  0 23 22  3  2  1  0 23 ... 22 21 20 19 18 23 22 21 20 19

Upvotes: 4

ecotax
ecotax

Reputation: 1953

I assume you want it to loop around (don't know why). if so, use modulo:

int index = (h + arr.size) % arr.size;

Upvotes: 2

Richard Salim
Richard Salim

Reputation: 129

Is using if statement not an option?

const int array_size = 24;
int arr[array_size] = { 1,3,4,5,...,2 }

 for(int i=0;i<array_size;i++)
 {
      for(int h=i-5; h<i; h++)
      {
        int arr_index = (h >= 0) ? h : (array_size + h);
         //do your things with arr[arr_index]
      }
 }

Upvotes: 0

user3621602
user3621602

Reputation: 73

you may also start the nested loop with something like:

for(int h=i-min(i,5);h<i;++h)
{
}

which let you process first 5 cells as well. also, if you are dealing with some kind of signal or image processing consider extending arr to have 29 elements with preceding 5 zeros or whatever value would be suitable, and start the first for-loop with 5th element.

Upvotes: -1

indigo
indigo

Reputation: 191

Using the modulo operator.

for (int i = 0; i < arr.size; i++)
{
  for (int h = 5; h > 0; h--)
  {
    const int array_length = sizeof(arr) / sizeof(arr[0]);
    int index = (i - h + array_length) % array_length; // Use 'sizeof(arr) / sizeof(arr[0])' to get the size of the array

    //things happen
  }
}

Upvotes: 1

Oleksandr Verhun
Oleksandr Verhun

Reputation: 854

Just make an if statement in nested loop. Something like this

for( int h = i-5; h < i; h++ )
{
   // do stuff        
   if( i == 0 )
        break;
}

Upvotes: -2

Related Questions