Search code examples
carraysif-statementindicesarray-difference

Deleting Elements from an Array based on their Position every 3 Elements


I created an array called elements_n which has the elements 0 to N-1 where N is 2. The below numbers are the elements of the array called elements_n:

0 1 

I have another array called Arr which has the following elements:

0 1 3 1 2 4 

If any of the first 3 elements of the array Arr are equal to the first element of elements_n which is 0, I would like to delete that element from the array called Arr. I then repeat the same process for the next 3 elements of the array Arr. So to explain myself better, I will use the following example:

Compare the first 3 elements of array Arr which are 0, 1, 3 to the first element of elements_n which is 0. Since Arr[0] == elements_n[0]. I delete Arr[0] from the array Arr.

Compare the next 3 elements of array Arr which are 1, 2, 4 to the second element of elements_n which is 1. Since Arr[3] == elements_n[1]. I delete Arr[3] from the array Arr. So the elements that should be left in the array Arr are:

1 3 2 4

When I implemented it myself in C programming with the code found below the end result is coming:

 1       3       3       2       2       4

Rather than:

  1       3       2       4

This is the code I implemented:

#include <stdio.h>
#include <stdlib.h>
#define N 2 

int main() {    
    unsigned *elements_n = malloc(N * sizeof(unsigned));

    for (int i = 0; i < N; i++) {
        elements_n[i] = i; //Created an array which has the elements 0 to N-1
    }
    printf("\n");

    unsigned Arr[6] = { 0, 1, 3, 1, 2, 4 };
    unsigned position_indices[2] = { 3, 3 };  //Moving every 3 elements in the Arr array. 

    int count = 0; 
    int index = 0;
    unsigned *ptr_Arr = &Arr[0];

    do {
        for (int i = 0; i < position_indices[count]; i++) {
            if (ptr_Arr[i] == elements_n[count]) {
                index = i + 1; //Index of the Arr element that has the same value as the element in the array elements_n 

                for (int j = index - 1; j < position_indices[count] - 1; j++) {
                    ptr_Arr[j] = ptr_Arr[j + 1];
                }
            }
        }
        printf("\n");
        ptr_Arr += position_indices[count] - 1; 
        count++;
    } while (count < 2);

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

    free(elements_n);

    return 0;
}

Solution

  • You need to keep track of how many elements you removed from the array.
    My solution:

    #include <stdio.h>
    #include <stddef.h>
    #include <assert.h>
    #include <string.h>
    
    size_t fancy_delete_3(const int elems[], size_t elemssize, int arr[], size_t arrsize)
    {
        assert(elems != NULL);
        assert(arr != NULL);
        assert(arrsize%3 == 0);
        assert(elemssize*3 == arrsize);
        // we need to count the removed elements, to know how much we need to shift left
        size_t removed = 0;
        // for each element in elems
        for (size_t i = 0; i < elemssize; ++i) {
            // check the three correponding elements in arr
            for (size_t j = i*3; j < (i+1)*3; ++j) {
                assert(j >= removed);
                const size_t pos = j - removed;
                // if elems[i] matches any of the corresponding element in arr
                if (elems[i] == arr[pos]) {
                    // remove element at position pos
                    assert(arrsize >= pos + 1);
                    // I don't think this can ever overflow
                    memmove(&arr[pos], &arr[pos + 1], (arrsize - pos - 1) * sizeof(int));
                    ++removed;
                    // array is one element shorter, so we can just decrease the array size
                    assert(arrsize > 0);
                    --arrsize;
                }
            }
        }
        // we return the new size of the array
        return arrsize;
    }
    
    #define __arraycount(x) sizeof(x)/sizeof(x[0])
    
    int main()
    {
        int elements_n[] = {0,1};
        int arr[] = {0,1,3, 1,2,4};
        size_t newsize = fancy_delete_3(elements_n, __arraycount(elements_n), arr, __arraycount(arr));
    
        printf("arr size=%zu {", newsize);
        for (size_t i = 0; i < newsize; ++i)
            printf("%d,", arr[i]);
        printf("}\n");
    
        return 0;
    }