Несмотря на то, что я уже ответил, мне не удается понять причину, по которой люди продвигаются через двойной цикл, повторяя данные снова и снова, с каждым сокращением.
Я полностью согласен со всеми советами по использованию контейнеров. Кроме того, решение для алгоритмов не требует контейнера (вы можете использовать его в собственном массиве), но контейнеры по-прежнему делают его проще и чище. Тем не менее ...
Я описал этот алгоритм в общем комментарии выше. вам не нужны вложенные циклы для этого. Вам нужен указатель чтения и указатель записи. Вот и все .
#include <iostream>
size_t remove_even(int *arr, size_t n)
{
int *rptr = arr, *wptr = arr;
while (n-- > 0)
{
if (*rptr % 2 != 0)
*wptr++ = *rptr;
++rptr;
}
return (wptr - arr);
}
int main()
{
int arr[] = { 2,10,3,5,8,7,3,3,7,10 };
size_t n = remove_even(arr, sizeof arr / sizeof *arr);
for (size_t i=0; i<n; ++i)
std::cout << arr[i] << ' ';
std::cout << '\n';
}
выход
3 5 7 3 3 7
Если вы думаете, что это не имеет значения, я предлагаю вам заполнить массив миллионами случайных целых чисел, а затем попробовать оба решения (подход с вложенными циклами и тот, что вы видите выше).
Использование std::remove_if
для собственного массива.
Приведенный только для ясности приведенный выше код в основном выполняет то же, что и стандартный алгоритм std::remove_if
. Все, что нам нужно, это предоставить итераторы (смещение массива и размер будут работать хорошо), и знать, как интерпретировать результаты.
#include <iostream>
#include <algorithm>
int main()
{
int arr[] = { 2,10,3,5,8,7,3,3,7,10 };
auto it = std::remove_if(std::begin(arr), std::end(arr),
[](int x){ return x%2 == 0; });
for (size_t i=0; i<(it - arr); ++i)
std::cout << arr[i] << ' ';
std::cout << '\n';
}
Те же результаты.