相对于另一个数组重新排列一个数组
Rearranging an array with respect to another array
我有 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++;
}
}
编辑:这个问题我以前也问过,但感觉自己措辞很烂,不知道怎么"bump"老post。
问题是您在循环的每次迭代中将 c 和 j 重置为零。因此,您只会比较每个数组中的第一个值。
另一个问题是,如果防御者数组的最后一个值小于攻击者数组的最后一个值,您将读到防御者数组的末尾。
另一个问题或可能只是奇怪的是,您在 if 语句的两个分支中同时递增 c 和 j。如果这是你真正想要的,那么 c 和 j 就没用了,你可以直接使用 i.
我会为您提供一些更新的代码,但是对于您要实现的目标的描述不够好;我只能指出明显的问题。
老实说,我没有看你的代码,因为我要在不到 2.30 小时后起床去上班,希望你不要对我有怨言。 .:)
我实现了 Eugene Sh 提出的 。在深入研究代码之前,您可能希望先阅读一些链接:
- qsort in C
- qsort and structs
- shortcircuiting
我的做法:
- 通过扫描
att
和 def
创建合并数组。
对合并后的数组进行排序。
用满足 ad 模式的值重新填充 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);
}
}
输出:
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
我有 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++;
}
}
编辑:这个问题我以前也问过,但感觉自己措辞很烂,不知道怎么"bump"老post。
问题是您在循环的每次迭代中将 c 和 j 重置为零。因此,您只会比较每个数组中的第一个值。
另一个问题是,如果防御者数组的最后一个值小于攻击者数组的最后一个值,您将读到防御者数组的末尾。
另一个问题或可能只是奇怪的是,您在 if 语句的两个分支中同时递增 c 和 j。如果这是你真正想要的,那么 c 和 j 就没用了,你可以直接使用 i.
我会为您提供一些更新的代码,但是对于您要实现的目标的描述不够好;我只能指出明显的问题。
老实说,我没有看你的代码,因为我要在不到 2.30 小时后起床去上班,希望你不要对我有怨言。 .:)
我实现了 Eugene Sh 提出的
- qsort in C
- qsort and structs
- shortcircuiting
我的做法:
- 通过扫描
att
和def
创建合并数组。 对合并后的数组进行排序。
用满足 ad 模式的值重新填充
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);
}
}
输出:
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