Я придумал следующую программу, чтобы сделать это, но это, кажется, не работает и входит в бесконечный цикл. Его работа подобна quicksort.
int main()
{
int arr[] = {1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1};
int N = 18;
int *front, *last;
front = arr;
last = arr + N;
while(front <= last)
{
while( (front < last) && (*front == 0) )
front++;
while( (front < last) && (*last == 1) )
last--;
if( front < last)
{
int temp = *front;
*front = *last;
*last = temp;
front ++;
last--;
}
}
for(int i=0;i<N;i++)
printf("%d ",arr[i]);
return 0;
}
Я вижу как минимум две проблемы в программе:
Проблема 1:
last = arr + N;
неверно. Это должно быть:
last = arr + N - 1;
, потому что
(arr + 0) points to 0th ele
(arr + 1) points to 1st ele
...
(arr + N -1) points to (N-1)th ele..which is the last element.
проблема2:
Далее ваша петля:
while(front <= last)
неверно и должно быть:
while(front < last)
в вашем случае, когда спереди и в последний раз становятся равными, ваш цикл продолжается, но Ни спереди, ни последняя не изменяются в этот момент, в результате чего бесконечный цикл.
Когда фронт и в последний раз становятся равными, он не имеет смысла продолжить, ваш массив было бы отсортировано к тому времени.
Ваш код не входит в бесконечный цикл в моей системе:
# gcc $CFLAGS -o test test.c
# ./test
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
Однако результат неверно. Я вижу 8 раз 1, но это должно быть 9 раз один.
Как указали некоторые люди, подводя итог, это гораздо проще подход:
#include <stdio.h>
int main()
{
int i;
int count;
int N = 18;
int arr[] = {1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1};
/* Sum up all elements */
i = 0;
count = 0;
while (i < N) count += arr[i++];
/* Overwrite the array */
i = 0;
count = N - count;
while (i < count) arr[i++] = 0;
while (i < N) arr[i++] = 1;
/* Print result */
for (i = 0; i < N; i++) printf("%d ",arr[i]);
}
Если вы нацелены на O (N), забудьте все Quicksorts (θ (NLOGN)), BUBLYORTS и т. Д. Нет. Классический алгоритм сортировки не достигает (n) для стандартных наборов данных, вы должны использовать двоичную природу набора.
int arr[] = {1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1};
int N = 18;
int i,s=0;
for(i=0;i<N;i++) s+=(arr[i]==0);
for(i=0;i<N;i++) arr[i]=!(i<s);
Вы делаете это слишком сильно на себе! Вы можете сделать это в O (n), зная только размер массива N
и сумма элементов S
. Поскольку двоичный массив имеет только две возможности для каждого элемента, зная, сколько существует одного элемента, и общий размер достаточно хорош.
Как только вы знаете, что просто выведите массив, содержащий S - N
Zeroes и n
, в этом порядке. Выполнено!
Альтернативный подход, который не требует суммирования его в первую очередь, и работает на месте: разместить указатель «Написать» W
на указателю index 0 и «чтение» R
при индексе N-1. Итайте обратно с указателем чтения, и каждый раз, когда вы столкнулись с 0, напишите «0» в w
и увеличивайте его. Когда вы достигаете начала с R
, заполните оставшуюся часть массива с помощью «1», используя w
.
видимо другой вопрос был закрыт... ваш алгоритм работает отлично. то, что я поместил в ответ на maddy в явном дублировании этого перенаправленного сюда человека, который закрыл его
int main()
{
int v[] = {1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1}; int *a, *b, i, n;
n = sizeof(v) / sizeof(int);
for (a = v, b = v + n - 1; a < b; ++a) {
if (*a) {
for (; *b; --b) if (a == b) goto end;
*a = 0; *b-- = 1;
}
}
end: for (i = 0; i < n; ++i) printf("%d%s", v[i], (i==n-1?"\n":",")); return 0;
}
сдвинул несколько строк вместе, чтобы он поместился на странице.... практически так же
.Репостинг здесь, как вопрос где я ответил, был закрыт (дубликат этого).
Мне жаль ответить на это, используя Python, но это упражнение, которое я хотел сделать. Код предназначен для условного, выводить этапы алгоритма. Конечно, перевод C не сложно, если вы осторожны, двигая указатель. Ваше здоровье!
# Put zeros on the left, ones on the right in one pass
a = [1,0,1,0,0,1,1,1,0,0,1,0,0,1,0,0,1,1,0,0,1,1,0,0,1,0,1]
cl = 0
cr = len(a) - 1
print a
while(True):
if cl + 1 == cr:
print 'last pass; adjacent elements'
if a[cl] == 0:
print 'a[%d] = 0; leave and exit loop' % (cl)
print 'final array:'
print a
break
if a[cl] == 1:
print 'a[%d] = 1; try to swap with a[%d]' % (cl, cr)
if a[cr] == 1:
print 'a[%d] = 1 as well; leave and exit loop' % (cr)
print 'final array:'
print a
break
else:
print 'a[%d] and a[%d] swapped; leave and exit loop' % (cl, cr)
a[cl] = 0
a[cr] = 1
print 'final array:'
print a
break
if a[cl] == 0:
print 'a[%d] = 0; leave and move on to a[%d]' % (cl,cl+1)
cl += 1
continue
else:
print 'a[%d] = 1 move to the right' % (cl)
while(True):
if a[cr] == 1:
print 'a[%d] cannot be moved to a[%d], try a[%d]' % (cl, cr, cr-1)
cr -= 1
continue
else:
print 'a[%d] swapped with a[%d]' % (cl, cr)
a[cr] = 1
a[cl] = 0
cr -= 1
cl += 1
print 'next up: a[%d]; right side blocked up to %d' % (cl,cr)
break
if (cl + 1) == cr:
break
Образец вывода:
[1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1]
a[0] = 1 move to the right
a[0] cannot be moved to a[26], try a[25]
a[0] swapped with a[25]
next up: a[1]; right side blocked up to 24
a[1] = 0; leave and move on to a[2]
a[2] = 1 move to the right
a[2] cannot be moved to a[24], try a[23]
a[2] swapped with a[23]
next up: a[3]; right side blocked up to 22
a[3] = 0; leave and move on to a[4]
a[4] = 0; leave and move on to a[5]
a[5] = 1 move to the right
a[5] swapped with a[22]
next up: a[6]; right side blocked up to 21
a[6] = 1 move to the right
a[6] cannot be moved to a[21], try a[20]
a[6] cannot be moved to a[20], try a[19]
a[6] swapped with a[19]
next up: a[7]; right side blocked up to 18
a[7] = 1 move to the right
a[7] swapped with a[18]
next up: a[8]; right side blocked up to 17
a[8] = 0; leave and move on to a[9]
a[9] = 0; leave and move on to a[10]
a[10] = 1 move to the right
a[10] cannot be moved to a[17], try a[16]
a[10] cannot be moved to a[16], try a[15]
a[10] swapped with a[15]
next up: a[11]; right side blocked up to 14
a[11] = 0; leave and move on to a[12]
a[12] = 0; leave and move on to a[13]
last pass; adjacent elements
a[13] = 1; try to swap with a[14]
a[13] and a[14] swapped; leave and exit loop
final array:
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Основная идея вашего алгоритма работает хорошо, и реализация может Быть упрощенным:
int a[] = {1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1};
int *begin = a;
int *end = begin + 17;
while (begin < end) {
if (*begin == 0)
begin++;
else if (*end == 1)
end--;
else {
*begin = 0;
*end = 1;
}
}
Обратите внимание, что (начало
Вы имеете в виду только массив 0
и 1
S?
Сумма всех n элементов, затем перезаписывает массив :)
int main() {
int arr[] = {1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1};
int N = sizeof arr / sizeof *arr; /* 18 */
int sum = 0;
int ndx;
for (ndx=0; ndx<N; ndx++) sum += arr[ndx];
for (ndx=0; ndx<N-sum; ndx++) arr[ndx] = 0;
for (ndx=N-sum; ndx<N; ndx++) arr[ndx] = 1;
}