Вы думаете в правильном направлении, но это одно из обстоятельств, когда объявление и определение простой функции для перемещения элементов вниз в массиве, перемещая индекс потери до конца, упростит вашу жизнь.Делая это таким образом, ваша единственная работа в теле вашего кода будет заключаться в предоставлении индекса проигрышей и отслеживании реального количества игроков, которые остаются с простым счетчиком.
Реализация функции дляперемещение данного индекса к последнему индексу для данного размера может быть аналогично следующему, где a
- массив, который необходимо переупорядочить, elem_idx
- индекс элемента для перемещения к последнему элементу в элементах sz
:
void element_to_last (int *a, int elem_idx, int sz)
{
if (elem_idx > sz - 1) { /* valdate index in range */
fprintf (stderr, "error: index %d out of range for size %d\n",
elem_idx, sz);
return;
}
int i = elem_idx, /* declare, initialize i, tmp */
tmp = *(a + i);
if (elem_idx == sz - 1) /* elem_idx is last index */
return; /* no-swap */
for (; i < sz - 1; i++) /* loop shifting elements down */
*(a + i) = *(a + i + 1);
*(a + i) = tmp; /* set last to tmp */
}
( примечание: вы хотите проверить, чтобы индекс элемента для перемещения в конец находился в допустимом диапазоне индексов, и нет необходимости выполнять своп, если индекс потериуже последний в диапазоне).
Короткий рабочий пример, в котором константа WRAP
просто контролирует вывод не более WRAP
значений на строку при печати результатов, а добавленное определение DEBUG
позволяет выводитьдополнительной информации, показывающей каждую операцию, если -DDEBUG
включен в строку компиляции, например,
#include <stdio.h>
#ifndef WRAP
#define WRAP 10
#endif
void element_to_last (int *a, int elem_idx, int sz)
{
if (elem_idx > sz - 1) { /* valdate index in range */
fprintf (stderr, "error: index %d out of range for size %d\n",
elem_idx, sz);
return;
}
int i = elem_idx, /* declare, initialize i, tmp */
tmp = *(a + i);
if (elem_idx == sz - 1) { /* elem_idx is last index */
#ifdef DEBUG
fprintf (stderr, " index %d (%d) is last index %d - no swap.\n",
elem_idx, tmp, sz - 1);
#endif
return; /* no-swap */
}
#ifdef DEBUG
printf (" index %d (%d) to end %d\n", elem_idx, tmp, sz - 1);
#endif
for (; i < sz - 1; i++) /* loop shifting elements down */
*(a + i) = *(a + i + 1);
*(a + i) = tmp; /* set last to tmp */
}
void prn_array (int *a, int sz, int wrap)
{
for (int i = 0; i < sz; i++) {
if (i && i % wrap == 0)
putchar ('\n');
printf (" %2d", *(a + i));
}
putchar ('\n');
}
int main (void) {
int a[] = {0,1,2,3,4,5,6,7,8,9}, /* original array order */
sz = sizeof a/sizeof *a, /* nelem in original */
n = sz, /* n tracks remaining size */
loser[] = {2,0,7,3,2,3,2,1,1}, /* order of losing indexes */
lsz = sizeof loser/sizeof *loser; /* nelem in loser array */
puts ("before:");
prn_array (a, sz, WRAP);
puts ("\nelimination\n(remove indexes 2,0,7,3,2,3,2,1,1):");
for (int i = 0; i < lsz; i++) {
element_to_last (a, loser[i], n > 0 ? n-- : n);
prn_array (a, sz, WRAP);
}
puts ("\nafter:");
prn_array (a, sz, WRAP);
}
( примечание: оставшиеся игроки, например, оставшееся количество элементов отслеживается с помощью n
, в то время как sz
сохраняет исходный размер всего массива.lsz
используется для размера массива loser
)
Пример Использование / Вывод
Без определения DEBUG
, выход просто показывает состояниемассив после проигравшего перемещается в конец оставшихся игроков:
$ ./bin/array_rotate
before:
0 1 2 3 4 5 6 7 8 9
elimination
(remove indexes 2,0,7,3,2,3,2,1,1):
0 1 3 4 5 6 7 8 9 2
1 3 4 5 6 7 8 9 0 2
1 3 4 5 6 7 8 9 0 2
1 3 4 6 7 8 5 9 0 2
1 3 6 7 8 4 5 9 0 2
1 3 6 8 7 4 5 9 0 2
1 3 8 6 7 4 5 9 0 2
1 8 3 6 7 4 5 9 0 2
1 8 3 6 7 4 5 9 0 2
after:
1 8 3 6 7 4 5 9 0 2
Выход DEBUG
С определенным DEBUG
, дополнительная информация, показывающая каждый index
и (value)
перемещается в показанный конечный индекс вместе с примечанием о том, был ли тогда конечный индекс проигравшим; в этом случае была предпринята попытка "no-swap"
:
$ ./bin/array_rotate
before:
0 1 2 3 4 5 6 7 8 9
elimination
(remove indexes 2,0,7,3,2,3,2,1,1):
index 2 (2) to end 9
0 1 3 4 5 6 7 8 9 2
index 0 (0) to end 8
1 3 4 5 6 7 8 9 0 2
index 7 (9) is last index 7 - no swap.
1 3 4 5 6 7 8 9 0 2
index 3 (5) to end 6
1 3 4 6 7 8 5 9 0 2
index 2 (4) to end 5
1 3 6 7 8 4 5 9 0 2
index 3 (7) to end 4
1 3 6 8 7 4 5 9 0 2
index 2 (6) to end 3
1 3 8 6 7 4 5 9 0 2
index 1 (3) to end 2
1 8 3 6 7 4 5 9 0 2
index 1 (8) is last index 1 - no swap.
1 8 3 6 7 4 5 9 0 2
after:
1 8 3 6 7 4 5 9 0 2
Просмотрите все и дайте мне знать, еслиу вас есть дополнительные вопросы.