0

I am trying to sort the multiple arrays based on the ascending order of one array. Here is the example:

int a[10] = {55140, 32294, 33321, 64321, 55312}
float b[10] = {11.11, 202.22, 3213.21, 144.32, 1.32}
const char* c[10] = {+, -, -, -, +}
unsigned char* d[10] = {22DS3K, 1FGJ29, 21FD43, 98DS03, 56DK23}

Now, after arranging the array 'a' in ascending order I want to sort the other arrays. The output should look like as follows:

a[10] = {32294, 33321, 55140, 55312, 64321}
b[10] = {202.22, 3213.21, 11.11, 1.32, 144.32}
c[10] = {-, -, +, +, -}
d[10] = {1FGJ29, 21FD43, 22DS3K, 56DK23, 98DS03}

Arranging the ascending order works fine. But, I am unable to sort the other arrays. I woould like to create a function to use it in my main function. Pleased to hear some suggestions.

I have seen the below post, but did not help me.

Sorting an array based on another in C

Here is the code that I have tried:

struct Data{
    int a[10]; 
    float b[10];
    const char* c[10];
    unsigned char* d[10];
} data;

int data_a[10];
float data_b[10];
const char* data_c[10];
unsigned char* d[10];


void ascending(int *t; int N){
int i,j,tmp;
for(i=0;j<N;j++){
  for(j=i+1;j<N;j++){
     if(t[i] > t[j]){
       tmp=t[i];
       t[i]=t[j];
       t[j]=tmp;
}}}}

int main(){
   int i;
   for(i=0;i<5;i++){
   data.a[i] = data_a[i];
   data.b[i] = data_b[i];
   data.c[i] = data_c[i];
   data.d[i] = data_d[i];
   }
   ascending(data.a, 5);
   for(i=0;i<5;i++){
      printf("Data is %d,%.2f,%s,%hhn\n", data.a[i],data.b[i],data.c[i],data.d[i]};
   }}

May I know if I am missing something or doing something completely wrong?

8
  • 2
    You should use a struct to group these related fields together. Keeping parallel arrays like this in sync is a total nightmare, and makes your code really messy and comlpex Commented Feb 8, 2022 at 19:10
  • Well, I grouped in the struct already. I justed posted that as an example. Though, thanks for your suggestion. Commented Feb 8, 2022 at 19:19
  • I'd suggest building a void swap() function that would take void * tab, int size, int index1, int index2, that would swap two elements of size size from table tab from indexes index1 and index2. In main() function (or wherever you want to sort your arrays) run an ordinary bubble sort algorythm. Every time you swap elements from table "a" do so for the rest. Commented Feb 8, 2022 at 19:21
  • 1
    "I grouped in the struct already" What's the problem then? Commented Feb 8, 2022 at 19:30
  • "I grouped in the struct already." Then there would only be 1 array, wouldn't it? Commented Feb 8, 2022 at 19:34

1 Answer 1

3

Keeping such a set of arrays in synch is a nightmare. What you seem to want is an array of structs instead of 5 separate arrays.

If I get you right, this is what would fit your needs better: (Also your initializers don't really match the data type of your arrays c and d.)

typedef struct data_s {
  int a;
  float b;
  const char *c;
  const char *d;
} data_t;

data_t data[10] = 
{
  [0] = {.a=55140, .b=11.11,   .c="+", .d="22DS3K"},
  [1] = {.a=32294, .b=202.22,  .c="-", .d="1FGJ29"},
  [2] = {.a=33321, .b=3213.21, .c="-", .d="21FD43"},
  [3] = {.a=64321, .b=144.32,  .c="-", .d="98DS03"},
  [4] = {.a=55312, .b=1.32,    .c="+", .d="56DK23"}
};

Then you can sort (just use qsort) for member a of your struct and as you will swap whole structs at once, the corresponding other members will be sorted accordingly:


int compare_a(const void *data1, const void*data2)
{
  return ((data_t*)data2)->a - ((data_t*)data1)->a;
}

int compare_d(const void *data1, const void*data2)
{
  return strcmp(((data_t*)data1)->d, ((data_t*)data2)->d);
}


int main(void)
{
...
  // optional:
  // Populate the missing fields with some default data
  size_t num_elem = sizeof(data)/sizeof(data[0]);
  for (size_t i = 5; i < num_elem; i++)
  {
    data[i].a = (int)i * 111;
    data[i].b = i * 1.11;
    data[i].c = "none";
    data[i].d = "";
  }

  // Sort for field a
  qsort(data, num_elem, sizeof (data[0]), compare_a);


  // Variant: Size unknown, use dynamic memory allocation
  size_t num_elem2 = 123;
  data_t *data2 = malloc(num_elem2 * sizeof (*data2));
  for (size_t i = 0; i < num_elem; i++)
  {
    data2[i].a = (int)i * 111;
    data2[i].b = i*1.11;
    data2[i].c = "none";
    data2[i].d = "";
  }
  // Sort for field d
  qsort(data, num_elem, sizeof (data[0]), compare_d);
}
Sign up to request clarification or add additional context in comments.

7 Comments

Many thanks for your answer. May I know, if it is possible to write the "for loop" inside the struct. I mean, inspite of directly writing the values, is it possible to extract from the other variables (maybe other struct variables or else from globle variables). Because, the values are not fixed and not the size too.
If the size of that array is not fixed at compile time, you have 2 options: If that is a local array, you can use a variable length array (VLA). A VLA cannot be initialized. You must use a loop or any other mechanism to populate it with values. If a local variabl is not sufficient for you, you must use dynamic memory allocation. With that you need to assign values on your own, as well.
I don't really get what you mean with "write the for loop inside the struct". Of course, you can use a for loop to assign values to the array fields. But that is not "inside the struct". A struct is a type. A type does not contain code and hence no loop. The struct definition in your question is so completely off (including initialization inside the type definition) that I suggest you revisit your text book about using structs and arrays and about difference between a type declaration and variable initializtion.
@ Gerhardh - Many thanks for your answer and comment. I mean, the for loop while initializing the variables. The values are not fixed, these are the output from the other functions.
Members in an array are just variables. Assign them as you would assign to any other variable. Wherever you get the values is up to you.
|

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.