相对于另一个arrays重新排列数组

我有两个并行的数组:

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

两者都是排序的,我想要做的是重新排列防御arrays的值,以便他们赢得更多的游戏(防御者[i]>攻击者[i])但我在如何交换防守arrays中的值时遇到问题。 所以实际上我们只针对攻击者使用防御arrays。

我有这个,但如果有的话,它没有太大的变化,我很确定我做得不对。 它被认为是一种powershell方法。

 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++; } } 

编辑:之前我确实问过这个问题,但我觉得好像我措辞严厉,并且不知道如何“碰撞”旧post。

老实说,我没看你的代码,因为我必须在不到2.30小时的时间内醒来上class,希望你对我没有感情…… 🙂


我实现了Eugene Sh提出的算法 。 在深入研究代码之前,您可能需要先阅读一些链接:

  1. 在C中的qsort
  2. qsort和结构
  3. 短路

我的方法:

  1. 通过扫描attdef创建合并数组。
  2. 合并数组排序。

  3. 使用满足广告模式的值重新填充def

  4. 完成再填充def与剩余值(即失败) *

*步骤3和4需要两次通过我的方法,也许它可以变得更好。

 #include  #include  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); } } 

输出:

 gsamaras@gsamaras:~$ gcc -Wall px.c gsamaras@gsamaras:~$ ./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 

问题是你在循环的每次迭代中将c和j重置为零。 因此,您只需要比较每个数组中的第一个值。

另一个问题是,在defenders数组的最后一个值小于攻击者数组的最后一个值的情况下,你将读取一个在defenders数组末尾的一个。

另一个问题或者可能只是奇怪的是你在if语句的两个分支中递增c和j。 如果这是你真正想要的,那么c和j是没用的,你可以使用i。

我会为你提供一些更新的代码,但是对你要实现的目标没有足够的描述; 我只能指出显而易见的问题。