2016-03-07 8 views
1

у меня есть 2 массивов, параллельно:Перегруппировка массива относительно другого массива

defenders = {1,5,7,9,12,18}; 
attackers = {3,10,14,15,17,18}; 

Оба сортируют, что я пытаюсь сделать, это изменить значение защищающихся буев так, что они выигрывают больше игр (защитник [i]> атакующий [i]), но у меня возникают проблемы с тем, как поменять значения в массиве защитников. Таким образом, в действительности мы работаем только с массивом защитников по отношению к атакующим.

У меня есть это, но если что-то не сильно меняется, и я уверен, что я не делаю это правильно. Предположим, что это метод грубой силы.

void rearrange(int* attackers, int* defenders, int size){ 
int i, c, j; 
int temp; 

for(i = 0; i<size; i++){ 
    c = 0; 
    j = 0; 
    if(defenders[c]<attackers[j]){ 
      temp = defenders[c+1]; 
      defenders[c+1] = defenders[c]; 
      defenders[c] = temp; 
      c++; 
      j++; 
    } 
    else 
     c++; 
     j++; 

    } 
} 

Edit: я задаю этот вопрос раньше, но я чувствую, как будто я сформулированный его ужасно, и не знал, как «поднять» старую должность.

+0

Вы инициализации '' c' и j' в начале каждого цикла. Это нормально? – MikeCAT

+0

Примечание: будьте осторожны, чтобы не выходить из-за пределов доступа. – MikeCAT

+0

@MikeCAT Я делал это так, чтобы c и j не стали огромными числами. У меня также было утверждение if, чтобы ограничить c + 1, но это не сильно повлияло. – Jude

ответ

0

Честно говоря, я не смотрел на свой код, так как я должен просыпаться в менее чем 2,30 часа, чтобы идти на работу, надеюсь, вы не будете иметь тяжелые чувства для меня .. :)


Я внедрил algorithm, предложенный Eugene Sh. Некоторые ссылки вы можете прочитать первым, прежде чем копаться в коде:

  1. qsort in C
  2. qsort and structs
  3. shortcircuiting

Мой подход:

  1. Создание объединенного массива с помощью сканирования оба att и def.
  2. Сортировка объединенного массива.

  3. Refill def со значениями, которые удовлетворяют требованиям .

  4. Полное заполнение def с остальными значениями ( Повержения) *.

* Шаги 3 и 4 требуют двух проходов в моем подходе, возможно, это может стать лучше.

#include <stdio.h> 
#include <stdlib.h> 

typedef struct { 
    char c; // a for att and d for def 
    int v; 
} pair; 

void print(pair* array, int N); 
void print_int_array(int* array, int N); 
// function to be used by qsort() 
int compar(const void* a, const void* b) { 
    pair *pair_a = (pair *)a; 
    pair *pair_b = (pair *)b; 
    if(pair_a->v == pair_b->v) 
     return pair_b->c - pair_a->c; // d has highest priority 
    return pair_a->v - pair_b->v; 
} 

int main(void) { 
    const int N = 6; 
    int def[] = {1, 5, 7, 9, 12, 18}; 
    int att[] = {3, 10, 14, 15, 17, 18}; 
    int i, j = 0; 
    // let's construct the merged array 
    pair merged_ar[2*N]; 
    // scan the def array 
    for(i = 0; i < N; ++i) { 
     merged_ar[i].c = 'd'; 
     merged_ar[i].v = def[i]; 
    } 
    // scan the att array 
    for(i = N; i < 2 * N; ++i) { 
     merged_ar[i].c = 'a'; 
     merged_ar[i].v = att[j++]; // watch out for the pointers 
     // 'merged_ar' is bigger than 'att' 
    } 
    // sort the merged array 
    qsort(merged_ar, 2 * N, sizeof(pair), compar); 
    print(merged_ar, 2 * N); 
    // scan the merged array 
    // to collect the patterns 
    j = 0; 
    // first pass to collect the patterns ad 
    for(i = 0; i < 2 * N; ++i) { 
     // if pattern found 
     if(merged_ar[i].c == 'a' &&  // first letter of pattern 
      i < 2 * N - 1   &&  // check that I am not the last element 
      merged_ar[i + 1].c == 'd') {  // second letter of the pattern 
      def[j++] = merged_ar[i + 1].v; // fill-in `def` array 
      merged_ar[i + 1].c = 'u'; // mark that value as used 
     } 
    } 
    // second pass to collect the cases were 'def' loses 
    for(i = 0; i < 2 * N; ++i) { 
     // 'a' is for the 'att' and 'u' is already in 'def' 
     if(merged_ar[i].c == 'd') { 
      def[j++] = merged_ar[i].v; 
     } 
    } 
    print_int_array(def, N); 
    return 0; 
} 

void print_int_array(int* array, int N) { 
    int i; 
    for(i = 0; i < N; ++i) { 
     printf("%d ", array[i]); 
    } 
    printf("\n"); 
} 

void print(pair* array, int N) { 
    int i; 
    for(i = 0; i < N; ++i) { 
       printf("%c %d\n", array[i].c, array[i].v); 
     } 
} 

Выход:

[email protected]:~$ gcc -Wall px.c 
[email protected]:~$ ./a.out 
d 1 
a 3 
d 5 
d 7 
d 9 
a 10 
d 12 
a 14 
a 15 
a 17 
d 18 
a 18 
5 12 18 1 7 9 
+0

Теперь я почувствовал, что должен добавить весь свой код, я немного не уверен, как добавить это, но я просмотрел значения в моем 2 массива (защитники/атакующие), которые динамически распределяются. Затем я называл mergesort на обоих массивах. Вот как у меня есть массив конечных результатов в моем исходном вопросе. Я не уверен, как легко я могу заставить все работать со структурой, но я могу попробовать – Jude

+0

Ну, я работал над своим подходом теперь @Jude, и он работает красиво. Надеюсь, поможет. : D Вы можете подумать, почему ваш подход не работал на первом месте. Также, хороший вопрос, +1. – gsamaras

+0

@ Зачем не использовать структуру? Поскольку ваши массивы динамически распределены? Это не имеет значения при использовании массивов (если они динамически распределены или нет!). – gsamaras

0

Проблема в том, что вы сбрасываете c и j на ноль на каждой итерации цикла. Следовательно, вы всегда сравниваете первое значение в каждом массиве.

Другая проблема заключается в том, что вы прочтете один конец конца массива защитников в случае, если последнее значение массива защитников меньше последнего значения массива злоумышленников.

Другая проблема или, может быть, просто странность в том, что вы увеличиваете как c, так и j в обеих ветвях оператора if. Если это то, что вы действительно хотите, то c и j бесполезны, и вы можете просто использовать i.

Я бы предложил вам обновленный код, но не достаточно хорошее описание того, чего вы пытаетесь достичь; Я могу только указать на очевидные проблемы.

Смежные вопросы