Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing elements from an array in C

I just have a simple question about arrays in C

What's the best way to remove elements from an array and in the process make the array smaller.

i.e the array is n size, then I take elements out of the array and then the array grows smaller by the amount that I removed it from.

basically I'm treating the array like a deck of cards and once I take a card off the top of the deck it shouldn't be there anymore.

EDIT: I'm going to drive myself crazy before the end of the day, thanks for all the help I'm trying the value swapping thing but it's not working right.

#include <stdio.h> #include <string.h> #include <stdlib.h>  enum faces{Ace = 0, Jack = 10, Queen, King}; char * facecheck(int d);  int draw(int deck, int i);  int main()  {      int deck[52], i, n;     char suits[4][9] =      {         "Hearts",         "Diamonds",         "Clubs",         "Spades"};       n = 0;      for(i = 0; i<52; i++)     {         deck[i] = n;         n++;      };        for(i=0; i<52; i++)     {                if(i%13 == 0 || i%13 == 10 || i%13 == 11 || i%13 == 12)             printf("%s ", facecheck(i%13) );         else printf("%d ", i%13+1);         printf("of %s \n", suits[i/13]);     }      draw(deck, i);       return 0;  }    char * facecheck(int d) {     static char * face[] =      {         "Ace",         "Jack",         "Queen",         "King" };      if(d == Ace)         return face[0];     else     {         if(d == Jack)              return face[1];         else         {             if(d == Queen)                 return face[2];             else              {                  if(d == King)                     return face[3];             }         }     }  }  int draw(int deck,int i )  {      int hand[5], j, temp[j];      for(i=0; i<52; i++)     {              j = i              };       for(i = 0; i < 5; i++)     {           deck[i] = hand[];            printf("A card has been drawn \n");           deck[i] = temp[j-1];           temp[j] = deck[i];           };            return deck; } 
like image 942
Rini Posny Avatar asked Apr 04 '13 20:04

Rini Posny


People also ask

How do I remove multiple elements from an array?

Approach 1: Store the index of array elements into another array which need to be removed. Start a loop and run it to the number of elements in the array. Use splice() method to remove the element at a particular index.

How do you remove an element from an array with value?

We can use the following JavaScript methods to remove an array element by its value. indexOf() – function is used to find array index number of given value. Return negavie number if the matching element not found. splice() function is used to delete a particular index value and return updated array.

What is the most efficient way to remove an element from an array?

Most efficient way to remove an element from an array, then reduce the size of the array.


2 Answers

There are really two separate issues. The first is keeping the elements of the array in proper order so that there are no "holes" after removing an element. The second is actually resizing the array itself.

Arrays in C are allocated as a fixed number of contiguous elements. There is no way to actually remove the memory used by an individual element in the array but the elements can be shifted to fill the hole made by removing an element. For example:

void remove_element(array_type *array, int index, int array_length) {    int i;    for(i = index; i < array_length - 1; i++) array[i] = array[i + 1]; } 

Statically allocated arrays can not be resized. Dynamically allocated arrays can be resized with realloc(). This will potentially move the entire array to another location in memory, so all pointers to the array or to its elements will have to be updated. For example:

remove_element(array, index, array_length);  /* First shift the elements, then reallocate */ array_type *tmp = realloc(array, (array_length - 1) * sizeof(array_type) ); if (tmp == NULL && array_length > 1) {    /* No memory available */    exit(EXIT_FAILURE); } array_length = array_length - 1; array = tmp; 

realloc will return a NULL pointer if the requested size is 0, or if there is an error. Otherwise it returns a pointer to the reallocated array. The temporary pointer is used to detect errors when calling realloc because instead of exiting it is also possible to just leave the original array as it was. When realloc fails to reallocate an array it does not alter the original array.

Note that both of these operations will be fairly slow if the array is large or if a lot of elements are removed. There are other data structures like linked lists and hashes that can be used if efficient insertion and deletion is a priority.

like image 103
Ben Avatar answered Sep 22 '22 20:09

Ben


You don't really want to be reallocing memory every time you remove something. If you know the rough size of your deck then choose an appropriate size for your array and keep a pointer to the current end of the list. This is a stack.

If you don't know the size of your deck, and think it could get really big as well as keeps changing size, then you will have to do something a little more complex and implement a linked-list.

In C, you have two simple ways to declare an array.

  1. On the stack, as a static array

    int myArray[16]; // Static array of 16 integers 
  2. On the heap, as a dynamically allocated array

    // Dynamically allocated array of 16 integers int* myArray = calloc(16, sizeof(int)); 

Standard C does not allow arrays of either of these types to be resized. You can either create a new array of a specific size, then copy the contents of the old array to the new one, or you can follow one of the suggestions above for a different abstract data type (ie: linked list, stack, queue, etc).

like image 44
Chris Farmiloe Avatar answered Sep 22 '22 20:09

Chris Farmiloe