4

Say I have an integer array like such

#define MAX 5
int bar [MAX] = {0};
int foo [MAX] = {3,1,0,0,0};

Now I'd like to shift this array so that all null entries are to the left, i.e. bar = {0,0,0,3,1}.

I thought I could do this by

  1. Finding the number of shifts I must perform
  2. Using memmove() to do the shift.

I solved 1. with the following loop

for (shift = MAX - 1; shift >= 0; --shift) {
    if (foo[shift]) break;
}

But I do not know how to use memmove() now to perform the shift, I attempted to do memmove(bar + shift, foo, MAX * sizeof(*foo)-1); but with no success.

Is memmove() the correct tool for the job? How can I circulate an integer array as described? What if this is happening inside a function where bar is a passed as a pointer?

Bernardo Meurer
  • 2,295
  • 5
  • 31
  • 52

1 Answers1

4
  • The formula you used to calculate shift does not give you the number of positions by which to shift.

  • You're not moving the correct number of bytes (MAX * sizeof(*foo)-1 is in no way based on the number of trailing zeroes).


#include <string.h>

#define MAX 5
int bar[MAX] = {0};
int foo[MAX] = {3,1,0,0,0};

int i;
int shift = 0;
for (i=MAX; i--; ) {
   if (foo[i]) {
      shift = MAX - (i + 1);
      break;
   }
}

memcpy(bar+shift, foo, (MAX-shift) * sizeof(*foo));
memcpy(bar, foo+(MAX-shift), shift * sizeof(*foo));

You can do it in-place since you know what values to "rotate in".

memmove(foo+shift, foo, (MAX-shift) * sizeof(*foo));
memset(foo, 0, shift * sizeof(*foo));

memmove must be used instead of memcpy since the destination and source buffers may overlap.

ikegami
  • 367,544
  • 15
  • 269
  • 518