1

I have 2 arrays, in parallel:

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

Both are sorted, what I am trying to do is rearrange the defending array's values so that they win more games (defender[i] > attacker[i]) but I am having issues on how to swap the values in the defenders array. So in reality we are only working with the defenders array with respect to the attackers.

I have this but if anything it isn't shifting much and Im pretty sure I'm not doing it right. Its suppose to be a brute force method.

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: I did ask this question before, but I feel as if I worded it terribly, and didn't know how to "bump" the older post.

14
  • You are initializing c and j in beginning of each loop. Is it OK? Commented Mar 7, 2016 at 1:21
  • Note: Be careful not to cause out-of-range access. Commented Mar 7, 2016 at 1:22
  • @MikeCAT I was doing this so c and j wouldn't become huge numbers. I also had an if statement to limit c+1 but it didn't do much. Commented Mar 7, 2016 at 1:24
  • 1
    Possible duplicate of Rearrange an array to be optimal in comparison to another array Commented Mar 7, 2016 at 1:26
  • 1
    @gsamaras yes I edited the my post to include my explanation Commented Mar 7, 2016 at 1:30

2 Answers 2

0

To be honest, I didn't look at your code, since I have to wake up in less than 2.30 hours to go to work, hope you won't have hard feelings for me.. :)


I implemented the algorithm proposed by Eugene Sh. Some links you may want to read first, before digging into the code:

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

My approach:

  1. Create merged array by scanning both att and def.
  2. Sort merged array.

  3. Refill def with values that satisfy the ad pattern.

  4. Complete refilling def with the remaining values (that are defeats)*.

*Steps 3 and 4 require two passes in my approach, maybe it can get better.

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

Output:

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
Sign up to request clarification or add additional context in comments.

6 Comments

Now I felt I should of added my entire code, I am a bit unsure how to add this but I scanned in the values into my 2 arrays (defender/attackers) that are both dynamically allocated. I then called mergesort on both arrays. Which is how I have the end result array in my original question. I am not sure how easily I can make things work with a struct but I can try
Well I worked on my approach now @Jude and it works nicely. Hope it helps. :D You can re-think why your approach didn't work in first place. Also, nice question, +1.
@Jude why not using a struct? Because your arrays are dynamically allocated? It doesn't make a difference when using the arrays (if they are dynamically allocated or not!!).
REALLY? I didn't see anywhere that mention @TomKarzes. Even if that's the case, I hope he will actually study my answer and learn! Thanks for the upvote anyway. :)
Well, it's a duplicate (and should have been closed as such). There were two other identical posts before this one. So yeah, homework assignment.
|
0

The problem is that you are resetting c and j to zero on each iteration of the loop. Consequently, you are only ever comparing the first value in each array.

Another problem is that you will read one past the end of the defenders array in the case that the last value of defenders array is less than last value of attackers array.

Another problem or maybe just oddity is that you are incrementing both c and j in both branches of the if-statement. If this is what you actually want, then c and j are useless and you can just use i.

I would offer you some updated code, but there is not a good enough description of what you are trying to achieve; I can only point out the problems that are apparent.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.