Переместить элемент в массиве по порядку - PullRequest
0 голосов
/ 26 октября 2011

Как переместить элемент в массиве в порядке или удалить из массива?

Пример: arr [3,3,2,1]

move(arr[0],arr[sizeof(arr)]);

arr [3,2,1, 3];

Я написал функцию, но правильно ли это?

void remove(int index, char *arr)
{
    arr[index]=NULL;
    for(int i=index;i<sizeof(arr)-1;i++)
        swap(arr[i],arr[i+1]);
}

Ответы [ 6 ]

2 голосов
/ 26 октября 2011

Ну, во-первых, я собираюсь предложить использовать std::vector вместо массива, поскольку вы используете C ++. Это сделает этот процесс намного проще. Что касается вашей функции, я хочу охватить несколько вещей ...

 arr[index] = NULL;

Если я правильно помню, NULL равен 0, так что это нормально. Однако я предполагаю, что у вас сложилось впечатление, что это указатель, а это не так. Хотя у вас может быть указатель на массив, каждый отдельный элемент массива не является указателем. Чтобы получить это, вам нужно будет передать символ **. Причина, по которой это работает в этом случае, заключается в том, что char действительно int.

sizeof(arr)-1

Это не даст вам количество элементов массива. Вы запросили размер arr, который будет возвращать размер типа данных указателя. Лучшим вариантом здесь будет перебирать арифметику с указателями, пока не дойдете до конца данных. Помните, что указатель на массив к концу дня все еще является просто указателем и не содержит каких-либо накладных расходов на сам массив. Он просто знает, на какой элемент он указывает.

1 голос
/ 26 октября 2011

sizeof(arr), когда arr объявлен как фактический массив с измерением, даст вам размер массива в байтах (на самом деле, C ++ не знает байтов, только char s, но давайте не будем сейчас вдаваться в это). Символ arr[sizeof(arr)] не имеет смысла: вы говорите компилятору получить элемент, индекс которого численно равен размеру массива в байтах, который всегда выходит за пределы. Кстати, чтобы получить размер массива в элементах , используйте: sizeof(arr) / sizeof(arr[0]).

sizeof(arr), когда char *arr даст вам размер указателя (обычно 4 или 8 байтов в зависимости от битности), независимо от того, насколько велик массив «ниже» этого указателя.

Даже когда вы исправите все это (и пару других более мелких вещей, таких как использование NULL в качестве целого числа), вы все равно будете просто перемещать элемент в конец массива, а не re -движу его.

Я предлагаю вам использовать std::vector и его erase метод. Если вы делаете много удалений с середины (и вы можете жить без произвольного доступа), рассмотрите вариант использования std::listего erase). Кроме того, вы также можете рассмотреть std::remove.

1 голос
/ 26 октября 2011

Это уже существует в стандартной библиотеке C ++ (std::rotate) и стандартной библиотеке C (memmove)

Если вы используете C ++, (поскольку он поставляется с функцией std::swap)и C не может поменяться с такими параметрами):

void remove(int index, char *arr, int len)
{
    if (len<=0)
        len = strlen(arr);
    std::rotate(arr+index, arr+index+1, arr+len);
    arr[len-1] = NULL;
}

Кроме того, в C ++ используйте std::vector или std::string, а не голый указатель char*.

Если вы используете C:

void remove(int index, char *arr, int len)
{
    if (len<=0)
        len = strlen(arr);
    memmove(arr+index, arr+index+1, len-index-1);
    arr[len-1] = NULL;
}

Если вы используете голые char* указатели, всегда передавайте длину.

1 голос
/ 26 октября 2011

Вам не нужно обнулять элемент или менять местами.

void remove(int index, char *arr)
{
    int i;
    for(i=index;i<strlen(arr)-1;i++)
        arr[i] = arr[i+1];
    arr[i] = NULL;  // i now points to last, "extra" element
}
0 голосов
/ 26 октября 2011

Это выглядит правильно, действительно. Вы должны различать случаи, когда вы хотите удалить элемент из массива или просто переместить его. Возможно, это хорошая идея для переноса счетчика (по количеству перемещений) в качестве параметра, а когда он равен длине массива (или 0, например), - элемент будет удален.

0 голосов
/ 26 октября 2011

Не меняйте местами ваши элементы, просто сдвиньте все правые выделенные элементы на одну позицию влево, чтобы перезаписать ваш элемент. Не забудьте уменьшить размер вашего массива.

...