utiliser qsort pour sortinger deux tableaux simultanément?

Je peux sortinger un tableau de pointeurs sur des mots de manière à ce qu’ils soient classés par ordre alphabétique. Le problème est que je dois AUSSI sortinger un tableau d’entiers (le nombre d’utilisations de ce mot spécifique) afin que les entiers soient au même endroit que leur mots respectifs:

mon 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]); } 

… fonction de comparaison V

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

Une chose simple à faire serait d’utiliser une structure pour stocker des paires mot / fréquence, puis de sortinger un tableau de ces structures.

Par exemple:

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

Ensuite:

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

Et:

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

La fonction standard qsort() ne peut pas faire ce que vous voulez directement. Tout le rest à part, comment sait-il (ou comment le dit-on) quels sont les deux tableaux à sortinger en parallèle?

Vous devez soit modifier la structure de données (utilisez un tableau d’un type de structure), soit écrire votre propre fonction de sorting. Des deux, changer la structure de données est probablement le plus facile.

Il existe une autre option – mais une solution quelque peu contournée. Vous pouvez créer un tableau d’ int avec des entrées telles que:

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

Vous transmettez ensuite ce tableau à la fonction de sorting, avec un comparateur qui connaît les adresses de base des deux tableaux. La fonction qsort() permute les données du tableau; le comparateur examine les données des autres tableaux. Les deux autres tableaux doivent être des variables globales (au moins la scope du fichier) ou vous avez besoin de variables globales qui sont des pointeurs pouvant être initialisés avec les adresses de base des deux tableaux.

Après le sorting, vous pouvez utiliser array1[index[i]] et array2[index[i]] pour accéder au i ème élément des tableaux sortingés.

Une autre option si vous êtes sur BSD: vous pouvez utiliser la fonction qsort_r() :

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

Le 'thunk' est un pointeur qui est transmis au comparateur en tant que premier argument. Vous pouvez l'utiliser avec le schéma de tableau d'index pour transmettre les pointeurs des deux tableaux au comparateur, de sorte que vous n'avez pas du tout besoin de variables d'étendue de fichier. Cependant, vous ne pouvez toujours pas effectuer deux échanges indépendants. Vous devez donc utiliser le schéma de tableau d'index.

Une approche qui pourrait vous être utile pour sortinger des tableaux parallèles: créez un tableau d’entiers ( size_t doit être ssortingctement correct) et initialisez-le avec les valeurs comsockets entre 0 et numWords-1 . Puis qsort ce tableau en utilisant une fonction de comparaison qui fait strcmp(dictionary[*(int *)p1], dictionary[*(int *)p2] , puis utilisez le tableau d’index sortingé pour permuter simultanément le dictionary et la frequency ( cela se fait très facilement en copiant, ou un peu moins facilement en place avec des swaps: voici un exemple de ce dernier).

Turix a probablement la meilleure solution: utiliser un tableau de structures au lieu de deux tableaux évite tout le problème.