Using qsort to sort two arrays at the same time?

I can sort the array of pointers to words so that they are ordered alphabetically, the problem is that I need to sort the integer array as well (the number of times a certain word is used) so that the integers are the same put their corresponding words:

my code:

for (i = 0; i < numWords; i++) {
    // prints out the words and their frequency respectively
    printf("%s - %d\n", dictionary[i], frequency[i]); 
}

//sorts the dictionary so that the words are 'alphabetical'
qsort(dictionary, numWords, sizeof(char *), rstrcmp);  
printf("\nafter qsort\n");  //checkmark

for (i = 0; i < numWords; i++) {
    // prints the word list alphabetically, but the frequencies are no longer matched
    printf("%s - %d\n", dictionary[i], frequency[i]); 
}

      

... comparison function V

int rstrcmp(const void *p1, const void *p2) {
    return strcmp(*(char * const *)p1, *(char * const *)p2);
}

      

+3


source to share


3 answers


The simplest would be to use a structure to store word / frequency pairs and then sort the array of those structures.

For example:

struct WordFrequency
{
    const char * word;
    int frequency;
} wordFreqs[numWords];        // Assumes numWords is static/global and constant...

      

Then:



for (i = 0; i < numWords; i++) {
    printf("%s - %d\n", dictionary[i], frequency[i]);
    wordFreqs[i].word = dictionary[i];
    wordFreqs[i].frequency = frequency[i];
}

//sorts the dictionary so that the words are 'alphabetical'
qsort(wordFreqs, numWords, sizeof(struct WordFrequency), wfcmp);  

for (i = 0; i < numWords; i++) {
    printf("%s - %d\n", wordFreqs[i].word, wordFreqs[i].frequency); 
}

      

and

int wfcmp(const void *p1, const void *p2) {
     return strcmp(((const struct WordFrequency *)p1)->word, ((const struct WordFrequency *)p2)->word);
}

      

+9


source


The standard function qsort()

may not work the way you want it to. Everything else, how does he know (or as you tell it) which two arrays are sorted in parallel?

You either need to change the data structure (use an array of structure type) or write your own sort function. Of the two, changing the data structure is probably easier.

There is another option - but somewhat distorted. You can create an array int

with entries such that:

for (int i = 0; i < N; i++)
    index[i] = i;

      

You then pass this array to the sort function, along with a comparator that knows the base addresses of the two arrays. The function qsort()

rearranges the data in the array; the comparator looks at data in other arrays. The other two arrays must be global (at least file area) variables, or you need global variables, which are pointers that can be initialized to the base addresses of the two arrays.



After sorting, you can use array1[index[i]]

and array2[index[i]]

to access the i

th element of the sorted arrays.

One more option if you are using BSD: you can use the function qsort_r()

:

 void qsort_r(void *base, size_t nel, size_t width, void *thunk,
              int (*compar)(void *, const void *, const void *));

      

"thunk" is a pointer that is passed to the comparator as the first argument. You can use this with the index-array schema to pass pointers to two arrays to the comparator, so you don't need the file scope variables. However, you still cannot perform two independent swaps, so you will have to use an index array schema.

+3


source


One approach you may find useful for sorting parallel arrays is to create an array of integers ( size_t

to be strictly correct) and initialize it with values ​​from 0 to numWords-1

. Then, qsort

the array uses the comparison function, which makes it strcmp(dictionary[*(int *)p1], dictionary[*(int *)p2]

, then use a sorted array of indices to simultaneously iterate how dictionary

, and frequency

(it is very easy to do by copying or slightly less easy to do on-site using swaps: here is an example of the latter).

Turix probably has a better solution, though - using an array of structures instead of two arrays avoids the whole problem.

+2


source







All Articles