Sort array C based on the contents of another array

I am trying to sort an array A whose elements are indexes. The indices refer to another array B , whose value will determine the order of A So, I would like to sort A so that B[ A[i] ] increases.

For instance:

  A = [0, 1, 4, 5, 7]
 B = [5, 3, 8, 2, 2, 7, 1, 6, 3, 9]

Sorted A will

  A '= [7, 4, 1, 0, 5]

Is this possible with the built-in C socket, or will I have to write my own implementation?

EDIT: These arrays are local variables of the function.

+6
source share
5 answers

If you want to use qsort , it is best to redo the indices in and the values โ€‹โ€‹from B into a structure, and then make a comparator based on the new array that will be structured. For instance:

 typedef struct { int index_from_A; int value_from_B; } index_value_wrapper; index_value_wrapper index_wrapper_array[5]; for (int i=0; i < 5; i++) { index_wrapper_array[i].index_from_A = A[i]; index_wrapper_array[i].value_from_B = B[A[i]]; } int comparitor (const void* lhs, const void* rhs) { return (lhs.value_from_B - rhs.value_from_B); } 

Now you can run qsort in a struct array, and from there you can extract the desired ordered sequence that you need for the original array A , without using a special sort function.

+6
source

If you have this, qsort_r provides a way to do this. You can specify it in an additional parameter. This context is passed to the comparison function. You can access this additional information to retrieve the necessary sorting information.

The Microsoft compiler has a similar one: qsort_s

+4
source

I think you can use qsort and a custom comparator

 int comparator(const void *x, const void *y) { return ( b[*(int*)x] - b[*(int*)y] ); } 
+3
source

Use your rule as a comparison function for qsort (as long as B is greater than A):

 #include <stdio.h> #include <stdlib.h> int A[] = {0, 1, 4, 5, 7}; int B[]= {5, 3, 8, 2, 2, 7, 1, 6, 3, 9}; int my_cmp(const void *a_, const void *b_,void *arg_) { const int *a = a_, *b = b_; if(B[*a] == B[*b]) return 0; else if (B[*a] < B[*b]) return -1; else return 1; } int main(int argc,char *arga[]) { int i; qsort(A,sizeof A/sizeof A[0] ,sizeof A[0],my_cmp); puts("Sorted A"); for(i = 0 ; i < sizeof A/sizeof A[0]; i++) { printf("A[%d] : %d B[A[%d]] : %d\n",i,A[i],i,B[A[i]]); } return 0; } 

This gives:

 $ ./a.out Sorted A A[0] : 4 B[A[0]] : 2 A[1] : 1 B[A[1]] : 3 A[2] : 0 B[A[2]] : 5 A[3] : 7 B[A[3]] : 6 A[4] : 5 B[A[4]] : 7 

Qsort_r is also available on many platforms (on linux, you will need #define _GNU_SOURCE before you enable <stdlib.h> to use it. Using this, you will change the comparison function, for example,

 int my_cmp(const void *a_, const void *b_,void *arg_) { const int *a = a_, *b = b_, *arg = arg_; if(arg[*a] == arg[*b]) return 0; else if (arg[*a] < arg[*b]) return -1; else return 1; } 

And call qsort_r like

 qsort_r(A,sizeof A/sizeof A[0] ,sizeof A[0],my_cmp,B); 
+2
source

Create another C array of type struct { int a_value; int b_value} struct { int a_value; int b_value} , initialize each element with the values โ€‹โ€‹of each index a and the value raised with b. Sort this, move the sorted C by copying a_values โ€‹โ€‹back to A.

Viola. No, this is a big violin. Voila!

+1
source

Source: https://habr.com/ru/post/888668/


All Articles