0

im having trouble "removing" my struct/array. Right now i can define max array to be size 10. I can fill the array with struct containing name, age, ect. My search function will let me search between a set of interval, say age 10 to 25. What i want my remove function do is remove those all those people between age 10-25. I should be able to re-enter new people into the database as long as it doesn't exceed my defined limit. Right now it seems to randomly remove stuff from the array.

struct database
{
    float age,b,c,d;
    char name[WORDLENGTH];
};
typedef struct database Database;

search func();

.........

    void remove(Database inv[], int *np, int *min, int *max, int *option)
    {
        int i;

        if (*np == 0)
        {
            printf("The database is empty\n");
            return;
        }

        search(inv, *np, low, high, option);

        if (*option == 1)
        {
            for (i = 0; i<*np; i++)
            {
                if (inv[i].age >= *low && inv[i].age <= *high)
                {
                   (*np)--;

                }
            }
        }
    }
xxFlashxx
  • 261
  • 2
  • 13
  • It does not remove anything from the array, but decreases the number of records. So if you find one match, it will be the last record in the array that will be "removed". – Weather Vane Oct 16 '16 at 08:43
  • min, max, low, high ? Is this your real code? Anyway, I don't remove an element in the array just by decrementing `np`. You need to copy/overwrite elements. – Support Ukraine Oct 16 '16 at 08:43
  • see http://stackoverflow.com/questions/15821123/removing-elements-from-an-array-in-c and http://stackoverflow.com/questions/37911285/fastest-way-to-remove-huge-number-of-elements-from-an-array-in-c – BeyelerStudios Oct 16 '16 at 08:44

2 Answers2

1

Right now it seems to randomly remove stuff from the array.

The items that your code removes are not random at all. This line

(*np)--;

removes the last item. Therefore, if the range contains two items that match the search condition at the beginning of the inv, your code would remove two items off the end. Things get a little more complicated if matching items are located in the back of the valid range of inv, so deletions start looking random.

Deleting from an array of structs is not different from deleting from an array of ints. You need to follow this algorithm:

  • Maintain a read index and a write index, initially set to zero
  • Run a loop that terminates when the read index goes past the end
  • At each step check the item at read index
  • If the item does not match the removal condition, copy from read index to write index, and advance both indexes
  • Otherwise, advance only the read index
  • Set new np to the value of write index at the end of the loop.

This algorithm ensures that items behind the deleted ones get moved toward the front of the array. See this answer for an example implementation of the above approach.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Hi! thanks for the tips. But im still a bit unsure how to actually implement this. In your example that you linked you mentioned if(keep_element(array[rd])), what is that? Is that where i loop through and check if the elements in the array is OUTSIDE of say ( inv[i].age < *low && inv[i].age > *high) where low and high is where i specified my age interval – xxFlashxx Oct 16 '16 at 09:42
  • @Alex `if(keep_element(array[rd]))` is the opposite of deletion condition. In your case, it's outside the interval, which is `inv[i].age < *low || inv[i].age > *high` (note the `||` instead of `&&`). – Sergey Kalinichenko Oct 16 '16 at 10:24
  • Hi, thanks. It's still not working... is there a way i can directly chat with you? – xxFlashxx Oct 16 '16 at 11:46
0

You can't remove an array element simply by decreasing the count of number of elements.

If you want to remove the n'th element in the array, you have to overwrite the n'th element with the (n+1)'th element and overwrite the (n+1)'th element with the (n+2)'th element and so on.

Something like:

int arr[5] = { 1, 2, 3, 4, 5};
int np = 5;

// Remove element 3 (aka index 2)
int i;
for (i = 2; i < (np-1); ++i)
{
    arr[i] = arr[i+1];
}
--np;

This is a simple approach to explain the concept. But notice that it requires a lot of copy so in real code, you should use a better algorithm (if performance is an issue). The answer from @dasblinkenlight explains one good algorithm.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63