1

I am attempting to make a program that takes an array and reverts it backwards however the program must do this to the array in groups of three. So if the user enters the numbers 1, 2, 3, 4, 5, 6 into the array the program will then output: 3, 2, 1, 6, 5, 4.

When I run the current program I get: 3 2 1 4 5 6. If anyone could help me figure out why that would be great as I am a little confused.

Here is my code:

int * numbersProcessFour(int *x, int size) 
{
    int i = 0, three = 3, six = 6, nine = 9;
    if (size < 4) 
    {
        for (i; i < three; i++)
        {
            reverse_array(x, three);
            printf("%d ", x[i]);
        }
    }else if (size > 3 && size < 7) 
    {
        for (i; i < three; i++)
        {
            reverse_array(x, three);
            printf("%d ", x[i]);
        }
        for (i; i < 6; i++)
        {
            reverse_array(x, three);
            printf("%d ", x[i]);
        }
    }
    else if (size > 6 && size < 10) 
    {
        for (i; i < three; i++)
        {
            reverse_array(x, three);
            printf("%d ", x[i]);
        }
        for (i; i < 6; i++)
        {
            reverse_array(x, three);
            printf("%d ", x[i]);
        }
        for (i; i < 9; i++)
        {
            reverse_array(x, three);
            printf("%d ", x[i]);
        }
    }
}
void reverse_array(int *x, int length)
{
    int i, temp;
    for (i = 0; i<length / 2; i++)
    {
        temp = x[i];
        x[i] = x[length - i - 1];
        x[length - i - 1] = temp;
    }
}
jjflyV7
  • 55
  • 1
  • 6
  • multiple ways of doing this. Could you try to create a 2D-array `arr[SIZE][3]` first, and then reverse only the first dimenstion. – Anoop Vaidya Apr 23 '16 at 04:13
  • 1
    You're way over thinking this. Just swap `x[0]` with `x[2]`, `x+=3` and `size-=3` until `size<3`. If `size==2`, swap `x[0]` with `x[1]`. – user3386109 Apr 23 '16 at 04:19
  • Create two pointers and swap the oth and 2nd array element. – Nirupa Apr 23 '16 at 04:57
  • @user3386109 your right about me overthinking it. This is killing me... I changed my reverse_array function per request, but that doesn't solve my problem of having the print out be the end result. still getting 3 2 1 4 5 6 – jjflyV7 Apr 23 '16 at 16:14

4 Answers4

1

You have branches for each multiple of 3, that is inefficient. One way to solve it is you can take the array as a split by 3 smaller arrays, and reverse on them. Also, reversing an array of 3 elements is the same as swap the 1st and the 3rd element.

int i;
int temp;
for (i = 0; i < count; i += 3) {
    if (i+2 >= count)
        break;
    temp = arr[i];
    arr[i] = arr[i+2];
    arr[i+2] = temp;
}
fluter
  • 13,238
  • 8
  • 62
  • 100
  • This is an adjustment made to my reverse_array function. The part i'm struggling the most with is the assigning the array to three smaller arrays. I feel like I am really overthinking it. – jjflyV7 Apr 23 '16 at 16:07
  • 1
    you don't need to create and assign smaller arrays, you can do it in place – fluter Apr 23 '16 at 23:56
1

A generalized version of numberProcessFour might look like this.

int reverse_array_mod(int *input, size_t size, int mod)
{
        int i, smod;

        /* Error: return modulus if size cannot be divided by mod */
        if(size%mod)
                return size%mod;

        smod = size/mod;

        for(i=0; i<smod; i++)
                reverse_array(input+i*mod, mod);

        /* return 0 on success */
        return 0;
}

Test

int main(int argc, char **argv)
{
        int a[] = {0, 1, 2, 3, 4, 5};
        int i, err, mod;

        for(mod=1; mod<5; mod++) {
                err = reverse_array_mod(a, 6, mod);
                if(err) {
                        fprintf(stderr, "Error %d, modulus %d invalid\n", err, mod);
                        return err;
                }

                for(i=0; i<6; i++)
                        printf("%d\n", a[i]);
                printf("\n");
        }

        return 0;
}

Result:

0
1
2
3
4
5

1
0
3
2
5
4

3
0
1
4
5
2

Error 2, modulus 4 invalid
Jan Christoph Terasa
  • 5,781
  • 24
  • 34
1

Continuing from your comment to fluter's answer, you may be over thinking it a bit. In order to swap the 1st and 3rd element in each 3-element partition of an array, you simply need to step though the array 3-elements at a time. You need to decide how you will handle any final partial partition, but since your goal is to swap the 1st and 3rd, there is no 3rd in anything less than a full partition, so the logical choice is to ignore any final partial partition.

A variant of what you and fluter have done incorporating a swap would be:

/* reverse 1st and 3rd element in each group of 3 */
void rev3 (int *a, size_t sz)
{
    if (sz < 3) return;
    size_t i;

    for (i = 0; i < sz; i += 3) {
        if (sz - i < 3) break;
        swap (&a[i], &a[i+2]);
    }
}

You can put it together with:

#include <stdio.h>

void rev3 (int *a, size_t sz);
void swap (int *a, int *b);

int main (void) {

    int a[] = {1,2,3,4,5,6,7,8,9};
    size_t i;

    rev3 (a, sizeof a/sizeof *a);

    for (i = 0; i < sizeof a/sizeof *a; i++) printf (" %2d", a[i]);
    putchar ('\n');

    return 0;
}

void swap (int *a, int *b)
{
    int t = *a;
    *a = *b;
    *b = t;
}

Example Use

When compiled and run it will give you the swap (reversal) of the 1st and 3rd elements throughout the array that you specify in your problem.

$ ./bin/revarr3
  3  2  1  6  5  4  9  8  7

There is no difference whether you use a separate swap or whether you include that operation in your reversal function. There is also no need to incur the additional overheard of calling a recursive function when a procedural approach will work. Look over all the answers and compare/contrast the differing ways to accomplish your goal.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • thank you for the vary detailed explanation. although I have a question about the swap function. I only have one array(pointer) going into that function. how does it still work? also if i wanted to remove any excess numbers how would i go about that? – jjflyV7 Apr 23 '16 at 22:05
  • Well, you have to swap pointers, not values, because when you pass the value as a parameter to any function (`swap` included), the function receives a *copy* of the value (stored in a different address), so if you attempt to swap the copy -- nothing changes back in the calling function. Therefore you pass a *pointer-to-the-value* to `swap` (e.g. `&array[i]`) rather than the value (`array[i]`). The only other way to do `swap` is to pass the whole-array plus 2 index values to swap (e.g. `swap (int *a, int i, int j)` to swap elements `i` and `j`), but you rarely see it done that way. – David C. Rankin Apr 23 '16 at 22:43
0

try this

int *numbersProcessFour(int *x, int size) {
    int i;
    for(i = 0; i + 3 < size; i += 3){
        reverse_array(x + i, 3);
    }
    if(size - i > 1)
        reverse_array(x + i, size - i);
    return x;
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70