так люди и катятся в пропасть
день добрый. не могу понять, почему вылетает программа. чисто теоретически должно работать (у одногруппников примерно такая же запись), но не работает
Задание: Удалить элементы, большие среднего арифметического в массиве.
Задание: Удалить элементы, большие среднего арифметического в массиве.
Абсолютно непонятная фраза. Какие-то ошибки компилятор выдаёт? Или результаты есть, но отличающиеся от корректных?
в условии выхода из цикла точно должно быть і, а не j? есть подозрение, что оно просто вылетает за пределы массива из-за бесконечного наращивания j
во-первых, при делении двух целых в Си результат будет округлённым целым
SA = sum / n;
во-вторых, при выводе результата этим циклом
for (int i = 0; i < n + m; i++)
вы пытаетесь вывести бльше чисел, чем нужно
в-третьих, изменять переменную цикла "for" внутри цикла вручную - нехорошо (а некоторые языки этого даже не позволяют)
это не ошибка, но дурной тон
однако ничего из перечисленного не должно вызывать вылета программы
ninelya, спасибо, поправила, хотя бы не вылетает)
CD_Eater, критиковать нужно %)
среднее поправила, вывод результата поправила
как поправить изменение переменной for внутри цикла не придумала, оставила так
теперь программа не вылетает, однако и не работает правильно:
и я не могу понять, как заставить её выводить последним 0, а не 4
5 элементов
исходный массив: 1 7 4 0 9
среднее 4,2
итоговый массив: 1 4 4
код
Потому, что сдвиг работает не так, как нужно: третья по счёту цифра (4) действительно сдвигается вперёд, однако, остальные цифры – нет. Поэтому третья цифра остаётся четвёркой, хотя должна быть следующая цифра 0. То есть, на место бОльшего числа копируете следующее и всё. Этого маловато (:
Так как у вас массив вообще статичный (память отжирается сразу под тысячу элементов, офигеть! да и выкинуть элементы нельзя), то полный сдвиг будет чересчур дорогим.
В конкретно этом случае, чтобы менять поменьше кода, я бы предложил заполнять новый массив как-то так:
А ещё проще вот так:
Ну и немного позанудствую, куда ж без этого (:
Для таких задач статические массивы неудобны (размер не поменять, элементы не выкинуть, памяти либо меньше, либо больше, чем необходимо). Используйте уже, наконец, вектора и будет счастье:
1. По непонятной причине вы в условиях цикла ставите "- 1", тем самым уменьшая количество обрабатываемых элементов на 1. Зачем?
2. Во внутреннем цикле вы увеличиваете i, а не j. Это ошибка.
На самом деле, вам здесь m, как дополнительный счетчик, не нужен. Достаточно на 1 уменьшать n после каждого удаления. При этом внутренний цикл переделать так:
for (int j = i + 1; j < n; j ++)
a[j - 1] = a[j];
Запись упрощается, и есть гарантия невыхода за границы массива.
А вообще, как я уже показывал выше, есть возможность сделать всё это за один проход. То, что вы пишете - это стандартный алгоритм remove_if. Идея его реализации в следующем: вы делаете себе два счётчика. Первый (в моем коде - i) определяет позицию массива откуда надо копировать. Второй (в моём коде - p) - куда надо копировать. Первый обходит весь массив. Второй увеличивается на 1 только в том случае, если элемент, на который указывает i, удовлетворят условию. При этом элемент, на который указывает i, копируется в место, на которое указывает p. В итоге, когда i достигнет конца массива, в первых элементах массива окажутся только те, которые удовлетворяют условию. А p будет содержать их количество. Что, собственно, и требуется.