views:

976

answers:

5

hi guys

how do i remove an element of an array and shift the reamining 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 abot this in the least amount of code!

+3  A: 

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.

PiNoYBoY82
I second the suggestion to use std::list. If you need to remove an element from the middle of a vector, it will require having to shift all the elements following it, which is really expensive (O(n) on average). However, removing an element from the middle of a list as you are traversing over it is a simple, O(1) operation.
newacct
+3  A: 

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())
zvrba
I don't thinking asking "Why" then answering with "because it's impossible" is very helpful. :/
GMan
I guess it's impossible as the memory has already been alocated, so the initial memory block will still contain information about a 5 item array.
Rodrigo
Rodrigo is correct.
zvrba
+3  A: 

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};
Steve Jessop
+8  A: 

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);
Adam Rosenfield
Please be aware that memmove() will only work for POD types, while OTOH almost any type can be used with a vector, even those that have a user-defined operator=().
j_random_hacker
+5  A: 

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

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

// delete 3
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 stack-allocated array.

If this was a dynamically allocated array, you could make room for a new array:

int *newArray = new int[8];

int index = 0;
for (int i = 0; i < 9; ++i)
{
    if (i != 2) // copy all but second
    {
        newArray[index++] = array[i];
    }
}

But why not use the standard library? The standard library has a remove function, along with vector to replace arrays.

And if you want to remove from any point, consider a list, for example, which can actually remove the value, rather than move it to the end.

GMan