Переставить все нулевые элементы массива в конец. С
С. Нужно переставить все нулевые элементы массива в конец. Код не обрабатывает 3 и больше нулей подряд, только два сортируются, остальные нули остаются на первоначальных местах. Подскажите пожалуйста, где ошибка?
#include <math.h>
#include <stdio.h>
int main() {
int N = 0;
float A[100];
do{ printf("Введите количество элементов\n");
scanf("%d", &N);
}while(N<1 || N>100);
printf("Введите элементы массива:\n");
for(int i=0; i<N; i++){
printf("A[%i]=", i);
scanf("%f", &A[i]); }
int i=0; int p=0;
for (i=0,p=0; i<N; i++){
while (A[i]==0 && i<N){
p=i;
for(p=i;p<N-1;p++) {
A[p]=A[p+1];
}
A[N-1]=0;
i++;
}
}
for(i=0; i<N; i++){
printf(" A[%i] = %3.2f \n", i, A[i]);
}
}
Ответы (2 шт):
int p=0;
for (int i=0; i<N; i++){
if (A[i]==0)
p++;
else
A[i-p] = A[i];
}
и заполнить p нулями конец
Исправлять ваш ответ трудно, камня на камне не останется. Правильнее будет выучить идиоматическое решение. У вас есть два индекса в массиве: i пробегает все позиции, j - пробегает только не нулевые.
Цикл на псевдокоде:
i = 0
j = 0
while i < n:
a[j] = a[i] # копируем всегда, так проще понять
if a[i] != 0:
j = j + 1 # продвигаем только если это был не ноль
i = i + 1 # продвигаем всегда
Этот цикл делает некоторые вещи лишние, например копирует нули. Зато его проще понять. Пока мы не встретили первый ноль, все копирования бесполезны, так i == j и мы копируем элемент сам в себя. Но как только встречен первый ноль, j отстанет от i и элементы начнут перемещаться влево. Сперва на одну позицию, затем на большее расстояние, зависит от числа встреченных нулей.
Когда копирование завершено, в конце массива остался мусор. j как раз указывает на место где этот мусор начинается. Его надо убрать:
while j < n:
a[j] = 0
j = j + 1
Ниже код на C, который это делает. Он отличается, но использует те же идеи:
// gcc -Wall -Wextra -std=c99 move_zeros.c
#include <assert.h>
#include <stdio.h>
// печатает массив
void print(int n, float a[/* n */]) {
for (int i = 0; i < n; ++i) {
if (i > 0) {
printf(" ");
}
printf("%f", a[i]);
}
printf("\n");
}
// переносит нули в конец массива
void move_zeros(int n, float a[/* n */]) {
int j = 0;
// копируем ненулевые элементы в начало массива
for (int i = 0; i < n; ++i) {
if (a[i] != 0) {
assert(j <= i);
// a[j++] - идиома С: записать значение и затем передвинуть индекс
a[j++] = a[i];
}
}
// заполняем нулями конец массива
for (; j < n; ++j) {
a[j] = 0;
}
}
int main() {
float a[] = {0, 1, 0, 2, 3, 0, 0, 4, 0, 0, 0, 5, 6};
int n = sizeof a / sizeof *a;
print(n, a);
move_zeros(n, a);
print(n, a);
}