Compter le nombre de comparaisons pour tri rapide

Fermé
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 - Modifié le 4 oct. 2022 à 15:03
mamiemando Messages postés 33372 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 novembre 2024 - 9 oct. 2022 à 23:44

Bonjour,

J'ai écrit un code pour partition d'un tableau et le code pour tri rapide. On me demande de compter le nombre de comparaisons, mais je sais pas comment faire.

Dois-je additionner le nombre de comparaisons de la partition du tableau de gauche et celui de droite ?

Comment compter le nombre de comparaisons entre éléments du tableau?

17 réponses

yg_be Messages postés 23342 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 21 novembre 2024 Ambassadeur 1 550
30 sept. 2022 à 20:21

bonjour,

ton programme exécute sans doute une instruction pour faire la comparaison.

tu peux probablement incrémenter un compteur chaque fois que cette instruction est exécutée.

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 15:05

Voici mon code

void echanger(int *a, int *b) {
    int tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}

int partition(int t[], int debut, int fin) {
    int valeur_pivot = t[fin];
    int indice_pivot = debut;
    int i;
    for (i = debut;i < fin; i++){
      if (t[i] <= valeur_pivot){
        echanger(&t[i], &t[indice_pivot]);
        indice_pivot += 1;
      }
    }
    echanger(&t[fin], &t[indice_pivot]);
    return indice_pivot;
}

void tri_segmentation(int t[], int debut, int fin) {
  int pivot;
  if (fin > debut) {
    pivot = partition(t, debut, fin);
    tri_segmentation(t, debut, pivot - 1);
    tri_segmentation(t, pivot + 1, fin);
  }
}
0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 15:07

J'ajoute un compteur dans ma boucle

if (t[i] <= valeur_pivot)

0
yg_be Messages postés 23342 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 21 novembre 2024 1 550
1 oct. 2022 à 13:48

montre ton code avec le compteur ajouté.

0
Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 101
2 oct. 2022 à 13:30

Oui, tu dois compter les comparaisons

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 15:08

J'ai fait:

int partition(int t[], int debut, int fin){
    int valeur_pivot = t[fin];
    int indice_pivot = debut;
    int i;
    int nb_comp = 0;
    for(i = debut; i < fin; i++){
      if (t[i] <= valeur_pivot){
        echanger(&t[i], &t[indice_pivot]);
        indice_pivot += 1;
        nb_compt++;
      }
    }
    echanger(&t[fin], &t[indice_pivot]);
    return indice_pivot;
}

On compte le nombre de comparaisons dans partition et je veux que dans tri segmentation ca soit le nombre de comparaison a droite et a gauche comme ca on aura le nombre total de comparaison dand tri rapide

0
yg_be Messages postés 23342 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 21 novembre 2024 1 550
2 oct. 2022 à 14:36

Pourquoi as-tu mis l'incrémentation du compteur dans le if?  Comprends-tu ce que fait le code?

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 15:09

Pour compter combien de comparaison on fait,dans if car on a une comparaison  c'est a dire 

t[i] <= valeur_pivot

Oui, je comprends le code vu que c'est moi qui l'ai écris

Voulez-vous que je détaille ce que fait le code a chaque itération ou bien c'est pas nécessaire

0
yg_be Messages postés 23342 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 21 novembre 2024 1 550
2 oct. 2022 à 19:09

Si tu veux compter le nombre de comparaisons, il faut incrémenter hors du if.

0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié le 3 oct. 2022 à 00:47

Salut Theo_0055,

Si tu incrémentes dans les accolades de la condition if, tu ne comptes pas le nombre de comparaisons effectuées, mais seulement le nombre de fois où la comparaison effectuée a été évaluée à "vrai".

Or, une comparaison évaluée à "faux" est aussi une comparaison faite, à compter.

En fait ... à chaque itération de la boucle, dans laquelle se trouve cette instruction if, tu fais cette comparaison... non ?

Vois-tu plus clairement maintenant la solution simple vers laquelle yg_be essaye de te guider ?

Si tu avais un code plus complexe, et tu voulais t'assurer de compter le nombre de fois que la condition du if est évaluée, tu peux aussi compter dans les parenthèses de ta condition if. Comme ceci :

if (nb_compt++, t[i]<=valeur_pivot) {

Cela n'affecte pas la comparaison, car avec l'opérateur virgule, seule la dernière instruction est évaluée pour les besoins du test. Tu es sûr d'être "au plus près" du test exécuté.

Mais, en l'occurrence, tu n'as pas besoin de cette astuce :-)

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
3 oct. 2022 à 07:33

Si je connais cette astuce sauf que je savais pas si je devrais l'utilser ici ou pas

Le fait d'écrire cela compte le nombre de comparaisons qu'on q'importe si le 

 
t[i]<=valeur_pivot est vrai ou faux,okkk j'ai compris

@yg_be je vois donc pourquoi je dois compter hors du if,okk

Ensuite,il se pose un autre probléme,vu que ma fonction partition il renvoie l'indice du pivot,je peux pas renvoyer en plus le nombre de comparaison

En fait dans tri rapide ,je veux que partition me donne le nombre de comparasions du tableau a gauche du pivot et a droite et je veux additionner les 2 pour avoir le nombre totale de comparasions dans tri rapide,quel astuce utiliser pour cela?

0
yg_be Messages postés 23342 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 21 novembre 2024 1 550
3 oct. 2022 à 08:52

Commence peut-être par montrer ton code modifié avec l'incrémentation hors du if.

Ensuite, pose-toi la question: comment déterminer si une comparaison est faite à gauche du pivot ou à droite?

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
3 oct. 2022 à 09:45

Dal a deja donne la solution pour partition

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 15:48

Si vous voulez hors du if sans utiliser l’astuce,on fait:

int partition(int t[],int debut,int fin){
    int valeur_pivot=t[fin];
    int indice_pivot=debut;
    int i;int nb_comp=0;
    for(i=debut;i< fin;i++){
      nb_compt++;
      if (t[i]<=valeur_pivot){
        echanger(&t[i], &t[indice_pivot]);
        indice_pivot+=1;
        nb_compt++
      }
    }
    echanger(&t[fin], &t[indice_pivot]);
    printf(« le nombre de comparaison est %d »,nb_compt);
    return indice_pivot;
}
0
yg_be Messages postés 23342 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 21 novembre 2024 1 550
3 oct. 2022 à 15:13

Je pense qu'il y a une erreur dans ce code.

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
3 oct. 2022 à 16:58

Une erreur dans la fonction partition? Ou bien la msniere dont je compte la comparaison?

0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
3 oct. 2022 à 17:00

Theo_0055, tu comptes dans le if en plus de en dehors...

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
3 oct. 2022 à 17:04

Sans utilise l'astuce nb_compt if(nb_compt,...)

Mon code le nb_compt je l'ai mis dans mon for et pas dans la boucle du if donc je compte en dehors du if,je vois pas pourquoi vous dites je compte aussi dans le if

0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
3 oct. 2022 à 18:25

Il semble que dans ce que tu as posté, tu mets nb_compt++ ligne 6 et ligne 10.

https://forums.commentcamarche.net/forum/affich-37698301-compter-le-nombre-de-comparaisons-pour-tri-rapide#15

Après, on ne sait pas ce que tu as dans ton vrai code, mais là, tu le mets à ces deux endroits...

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
3 oct. 2022 à 19:29

Ah desole je suis trompé ,j'ai oublie de effacer en copiant coller le code le nb_compt dans le if

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
4 oct. 2022 à 12:08

maintenant que j'ai montré comment compter le nombre de comparasion dans la fonction partition,comment je dois m'y prendre dans la fonction tri rapide svp

0
yg_be Messages postés 23342 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 21 novembre 2024 1 550
4 oct. 2022 à 13:07

Qu'as-tu essayé?

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 15:27

En fait comme ce que j'ai dit je suis bloqué

sachant que ma fonction partition me renvoie l'indice du pivot,je peux pas renvoyer aussi le nombre de comparaisons car dans mon exo on n'a dit ne pas changer les entrees et sorties des fonctions

du coup lorsque j'appelle cette fonction dans tri rapide,je perds les info sur le nombre de comparaisons,je sais pas comment le stocker

0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié le 4 oct. 2022 à 15:40

Est-ce qu'il t'est permis d'utiliser des variables globales ?

Si ton code est dans un module, tu peux même en faire une variable globale statique, afin qu'elle ne soit visible que dans le module et créer une fonction helper qui en récupère la valeur pour le programme faisant usage du module.

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1 > [Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024
4 oct. 2022 à 17:19

Oui je peux .Je voulais le faire mais je savais pas comment m'y prendre

0
mamiemando Messages postés 33372 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 novembre 2024 7 802
4 oct. 2022 à 15:55

Bonjour,

Le plus simple est de passer l'adresse d'un compteur à ta fonction partition et de définir une fonction compare qui prend en paramètre les deux valeurs à comparer et l'adresse du compteur.

#include <stdbool.h>

bool compare(int a, int b, unsigned *pnum_comparaisons) {
  *pnum_comparaisons++; // On incrémente le compteur
  return a <= b;
}


size_t partition(int t[], size_t debut, size_t fin, unsigned *pnum_comparaisons) {
  *pnum_comparaisons = 0; // Initialisation du compteur
  ...
  // if (t[i] <= valeur_pivot) {
  if (compare(t[i], valeur_pivot, pnum_comparaisons)) {
  ...
}

int main() {
  unsigned num_comparaison;
  ...
  partition(t, debut, fin, &num_comparaison);
  ...
}

Bonne chance

0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
4 oct. 2022 à 17:07

Salut mamiemando,

Si je comprends bien ce que Theo_0055 nous dit, il n'a pas le droit de modifier le prototype de sa fonction :

int partition(int t[],int debut,int fin);
0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 17:32

Et donc par cette methode ma fonction partition va retourner l'indice de mon pivot et grace au pointeur qui compte le nombre de comparaison je peux connaitre aussi mon nombre de comparaison.Oui j'aime bien cette facon de faire mais la facon de faire de @Dal je suis aussi curieux 

mais du coup avec cette methode que je comprends et j'aime beaucoup,j'ai bien reflechir mais je vois pas comment elle pourra me permettre de compter le nombre de comparaison a gauche et a droite et de faire la somme pour qu'il me donne le nombre de comparaisons effectué dans tri rapide

ou bien mon raisonnement d'additionner le nopbre de comparaison a gauche et a droite n'est pas ici adapte pour le probleme ou n'est pas judicieuse?

0
mamiemando Messages postés 33372 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 novembre 2024 7 802 > Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023
Modifié le 5 oct. 2022 à 14:50

@[Dal] StatutContributeur Ah ok ! Je n'ai pas vu cette contrainte mais c'est peut-être moi qui ai mal lu / interprété. Quoi qu'il en soit, la méthode que je propose reste valide en utilisant une variable globale au lieu d'un uint*, mais bon les variables globales, c'est le mal.

@Theo_0055 StatutMembre Peux-tu indiquer si c'est effectivement moi qui ai mal compris :

  • Peut-on modifier le prototype de la fonction partition ?
  • Peut-on utiliser des variables globales ?

comment elle pourra me permettre de compter le nombre de comparaison a gauche et a droite et de faire la somme pour qu'il me donne le nombre de comparaisons effectué dans tri rapide

Je ne vois pas trop l'intérêt de distinguer ces deux décomptes. 

Si tu veux vraiment distinguer ces deux compteurs, c'est un détail mineur d'implémentation. En effet, il suffirait alors de passer modifier le prototype de compare pour passer en paramètre l'index i et l'index du pivot pour savoir si c'est une comparaison à gauche ou à droite (il faudrait juste définir laquelle est la "comparaison à gauche" et laquelle est la "comparaison à droite"). En fonction de ce test, on maintient deux compteurs au lieu d'un seul (et donc on a soit deux variables globales, soit deux uint*).

bool compare(int * tab, uint i, uint j, unsigned *pnum_left_cmp, unsigned *pnum_right_cmp) {
  if (i < j)
    *pnum_left_cmp++;
  else if (i > j)
    *pnum_right_cmp++;
  return tab[i] <= tab[j];
}

Bonne chance

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1 > mamiemando Messages postés 33372 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 novembre 2024
9 oct. 2022 à 20:37

Ah merci !!!!!????

0
mamiemando Messages postés 33372 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 novembre 2024 7 802 > Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023
9 oct. 2022 à 23:44

Faut-il en conclure que ton problème est résolu ? Si oui, merci basculer la discussion en résolue, comme expliqué ici.

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 17:22

En fait j'ai juste pas le droit de modifier ma fonction tri rapide

bon le tri rapide de l'exo il est de la forme:int tab[],int n et la fonction tri rapide que j'ai donne ici dans ce forum est en quelque sorte un tri_rapide_rec aue je peux appeler dans ma fonction tri_rapide(int tab[],int n) .Ca ce n'est pas un probleme

partition est une fonction auxiliaire utilise par moi pour simplifier le code plutot que d'ecrire le code tri rapide d'un coup

0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
4 oct. 2022 à 18:24

J'avoue ne pas comprendre ton problème et ton histoire de somme de comparaisons à gauche et à droite, et pour être très honnête, je n'ai pas envie de me plonger dans la vérification de la pertinence de ton algorithme de tri (ce que je n'ai pas fait).

Pour moi, les choses sont simples : si ton compteur est incrémenté au seul endroit où sont exécutées les opérations à comptabiliser, il te suffit de le mettre à 0 avant d'exécuter ton code et de consulter sa valeur modifiée par l'effet de cette incrémentation une fois le traitement terminé.

Si tu as le droit de modifier le prototype de la fonction partition(), alors tu peux (devrais) te passer de variable globale (même statique) et tu pourras récupérer la valeur du compteur dans la fonction appelante comme proposé par mamiemando.

Si ce n'est pas à cette fonction appelante d'utiliser le résultat du comptage, et que tu n'a pas le droit de modifier le prototype de la fonction appelante qui ne te permettrait pas de récupérer cette valeur d'une façon ou d'une autre, alors faire comme j'ai proposé reste une possibilité, mais si tu peux faire autrement, c'est effectivement mieux de ne pas utiliser de variable globale.

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
4 oct. 2022 à 18:47

Ah ok je vois en fait pas besoin de compter faire a gauche et a droite 

Donc on a:

void echanger(int *a, int *b) {
    int tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}


bool compare(int a, int b, unsigned *pnum_comparaisons) {
  *pnum_comparaisons++; // On incrémente le compteur
  return a <= b;
}

size_t partition(int t[], size_t debut, size_t fin, unsigned *pnum_comparaisons) {
  *pnum_comparaisons = 0; // Initialisation du compteur
 
    int valeur_pivot = t[fin];
    int indice_pivot = debut;
    int i;
    for (i = debut;i < fin; i++){
      if (compare(t[i], valeur_pivot, pnum_comparaisons)) {
        echanger(&t[i], &t[indice_pivot]);
        indice_pivot += 1;
      }
    }
    echanger(&t[fin], &t[indice_pivot]);
    return indice_pivot;
}



void tri_segmentation(int t[], int debut, int fin) {
  int pivot;
  unsigned num_comparaison;
  if (fin > debut) {
    pivot = partition(t, debut, fin, &num_comparaison);
    tri_segmentation(t, debut, pivot - 1);
    tri_segmentation(t, pivot + 1, fin);
  }
}
0