user103572
user103572

Reputation: 489

Remove an array element and shift the remaining ones

How do I remove an element of an array and shift the remaining elements down. So, if I have an array,

array[]={1,2,3,4,5} 

and want to delete 3 and shift the rest so I have,

array[]={1,2,4,5}

How would I go about this in the least amount of code?

Upvotes: 38

Views: 391275

Answers (11)

// Shift elements to fill the gap caused by the deleted index
for (int i = 2; i < size-1; ++i) {
           array[i] = array[i + 1];
      }

   --size;  //decrement size of the array after deleting an index
  

**Note: If you encounter issues where doubling any element after deleting, consider using 'size' instead of 'size-1'. The choice depends on your specific scenario. Alternatively, when printing the array using a for loop, make sure not to iterate up to i < maxSize, only iterate up to the current size.

Upvotes: 0

Pavan Chandaka
Pavan Chandaka

Reputation: 12731

This question is bit old. Try using standard library provided containers. These are designed by experts and very well tested. Moreover future developments of standard library algorithms are designed to suite these standard library containers.

If for some reason you have to stick to array, then try using std::array

std::array<int, 5> array = { 1,2,3,4,5 };

//std::remove - The elements that are not deleted are moved to the front of the array,
//and returns the iterator of the element from where it can be completely erased.
auto itr = std::remove(array.begin(), array.end(), 3);

//New array with new size
std::array<int,4> newArray;

std::copy(array.begin(), itr, newArray.begin());

The same thing can be done without using std::array also. But as said earlier for many other benifits prefer to go with std::array

int array[] = { 1,2,3,4,5 };    
auto itr = std::remove(std::begin(array), std::end(array), 3);    
int newArray[4];    
std::copy(std::begin(array), itr, std::begin(newArray));

Upvotes: 0

hyono
hyono

Reputation: 1

It reduces length indeed. However, if we speak about int arrays, there is a difference between length and size. Size tells us about a capacity of a given array, how much we can store in it. Length of an array tells us about how many items are there actually.

Upvotes: 0

MichaelJP
MichaelJP

Reputation: 11

Programming Hub randomly provided a code snippet which in fact does reduce the length of an array

for (i = position_to_remove; i < length_of_array; ++i) {
        inputarray[i] = inputarray[i + 1];
}

Not sure if it's behaviour that was added only later. It does the trick though.

Upvotes: 1

Yuri Feldman
Yuri Feldman

Reputation: 2584

Just so it be noted: If the requirement to preserve the elements order is relaxed it is much more efficient to replace the element being removed with the last element.

Upvotes: 2

JosephH
JosephH

Reputation: 8815

If you are most concerned about code size and/or performance (also for WCET analysis, if you need one), I think this is probably going to be one of the more transparent solutions (for finding and removing elements):

unsigned int l=0, removed=0;

for( unsigned int i=0; i<count; i++ ) {
    if( array[i] != to_remove )
        array[l++] = array[i];
    else
        removed++;
}

count -= removed;

Upvotes: 2

GManNickG
GManNickG

Reputation: 503805

You just need to overwrite what you're deleting with the next value in the array, propagate that change, and then keep in mind where the new end is:

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

// delete 3 (index 2)
for (int i = 2; i < 8; ++i)
    array[i] = array[i + 1]; // copy next element left

Now your array is {1, 2, 4, 5, 6, 7, 8, 9, 9}. You cannot delete the extra 9 since this is a statically-sized array, you just have to ignore it. This can be done with std::copy:

std::copy(array + 3, // copy everything starting here
          array + 9, // and ending here, not including it,
          array + 2) // to this destination

In C++11, use can use std::move (the algorithm overload, not the utility overload) instead.

More generally, use std::remove to remove elements matching a value:

// remove *all* 3's, return new ending (remaining elements unspecified)
auto arrayEnd = std::remove(std::begin(array), std::end(array), 3);

Even more generally, there is std::remove_if.

Note that the use of std::vector<int> may be more appropriate here, as its a "true" dynamically-allocated resizing array. (In the sense that asking for its size() reflects removed elements.)

Upvotes: 55

Steve Jessop
Steve Jessop

Reputation: 279225

std::copy does the job as far as moving elements is concerned:

 #include <algorithm>

 std::copy(array+3, array+5, array+2);

Note that the precondition for copy is that the destination must not be in the source range. It's permissible for the ranges to overlap.

Also, because of the way arrays work in C++, this doesn't "shorten" the array. It just shifts elements around within it. There is no way to change the size of an array, but if you're using a separate integer to track its "size" meaning the size of the part you care about, then you can of course decrement that.

So, the array you'll end up with will be as if it were initialized with:

int array[] = {1,2,4,5,5};

Upvotes: 11

Adam Rosenfield
Adam Rosenfield

Reputation: 400174

You can use memmove(), but you have to keep track of the array size yourself:

size_t array_size = 5;
int array[5] = {1, 2, 3, 4, 5};

// delete element at index 2
memmove(array + 2, array + 3, (array_size - 2 - 1) * sizeof(int));
array_size--;

In C++, though, it would be better to use a std::vector:

std::vector<int> array;
// initialize array...

// delete element at index 2
array.erase(array.begin() + 2);

Upvotes: 23

zvrba
zvrba

Reputation: 24546

You can't achieve what you want with arrays. Use vectors instead, and read about the std::remove algorithm. Something like:

std::remove(array, array+5, 3)

will work on your array, but it will not shorten it (why -- because it's impossible). With vectors, it'd be something like

v.erase(std::remove(v.begin(), v.end(), 3), v.end())

Upvotes: 6

PiNoYBoY82
PiNoYBoY82

Reputation: 1658

Depending on your requirements, you may want to use stl lists for these types of operations. You can iterate through your list until you find the element, and erase the element. If you can't use lists, then you'll have to shift everything yourself, either by some sort of stl algorithm or manually.

Upvotes: 3

Related Questions