Aide programme C++
Résolu/Fermé
Ratblanc68
Messages postés
4
Date d'inscription
vendredi 25 janvier 2013
Statut
Membre
Dernière intervention
25 janvier 2013
-
Modifié par Ratblanc68 le 25/01/2013 à 18:38
mamiemando Messages postés 33320 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 octobre 2024 - 25 janv. 2013 à 22:37
mamiemando Messages postés 33320 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 octobre 2024 - 25 janv. 2013 à 22:37
A voir également:
- Aide programme C++
- Programme demarrage windows 10 - Guide
- Désinstaller programme windows 10 - Guide
- Programme démarrage windows 10 - Guide
- Forcer la fermeture d'un programme - Guide
2 réponses
mamiemando
Messages postés
33320
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
17 octobre 2024
7 798
25 janv. 2013 à 22:24
25 janv. 2013 à 22:24
Alors la méthode la plus simple c'est un bon vieux qsort :
http://www.cplusplus.com/reference/cstdlib/qsort/
Le problème de cette approche (mais qui est amplement suffisante dans ton cas) c'est qu'elle suppose que l'opérateur "-" a un sens pour les valeurs comparées et que - retourne une valeur nulle en cas d'égalité, négative si a précède b, positive sinon. C'est ce qu'on fait traditionnellement en C. Si on veut trier dans l'autre sens, il faut écrire une autre fonction compare. Ça tombe bien pour des chaînes de caractères, strcmp se comporte exactement comme ça.
Bon maintenant c'est cool, mais ça c'est du C, et à chaque fois que le type de "values" change, on doit réécrire une fonction "compare". Alors voyons comment en C++ on peut faire ça avec n'importe quel type, en supposant que ce type a un opérateur <.
L'idée comme on veut garder les doublons, c'est d'utiliser un multiset (si on voulait dégager les doublons, on utiliserait un set).
http://www.cplusplus.com/reference/set/multiset/
Avant rentrer dans le vif du sujet si tu n'as jamais utilisé la STL, je te conseille de lire ceci pour te familiariser avec la notion de container et d'iterator :
https://forums.commentcamarche.net/forum/affich-37604421-introduction-a-la-stl-en-c-standard-template-library
Revenons à ton problème. Ce premier programme montre comment on insère les valeurs stockées dans "values" dans deux multisets, l'un triant par ordre croissant, l'autre dans l'ordre décroissant.
Résultat :
Détaillons un peu le code.
Le code de l'opérateur << est juste là pour écrire facilement un mutliset dans un flux, l'intérêt du programme réside dans ton cas surtout dans la partie où l'on déclare s_increasing et s_decreasing.
Si tu as pris le temps de regarder le lien ci-dessus, tu verras que pour un multiset les paramètres template Compare et Alloc sont optionnels. Dans le code ci-dessus je me suis reposé la dessus :
- dans la déclaration de s_increasing j'ai omis les paramètres template Compare (qui prend donc pour valeur par défaut std::less<value_t>, donc un tri effectué selon l'opérateur <) et Alloc ;
- dans la déclaration de s_decreasing j'ai précisé l'ordre (qui repose pour le coup sur l'opérateur >).
Revenons sur <<. Tu vois que l'on itère sur chaque valeur contenu dans un multiset générique et qu'on écrit les valeurs rencontrées dans un flux de sortie. Bon c'est bien tout ça mais j'imagine que maintenant, ce que tu veux, c'est stocker les valeurs triées dans un tableau (que je vais nommer "triees" dans ce qui suit). C'est ce que va faire ma fonction order_values :
- elle lit un tableau de taille n nommé "in"
- elle répercute le contenu dans un tableau de taille n nommé "out"
Évidemment je veux me laisser la possibilité d'ordonner selon différents foncteurs Compare (le mot est lâché), pas seulement std::less. Ça va donc être un paramètre template de ma fonction. Comme je veux pouvoir trier n'importe quel tableau de valeur (par exemple T = int, T= double, ou T = ma_classe) c'est aussi un paramètre template.
Sortie :
Bonne chance
http://www.cplusplus.com/reference/cstdlib/qsort/
#include <stdio.h> #include <stdlib.h> int values[] = { 40, 10, 100, 90, 20, 25 }; int compare (const void * a, const void * b) { return ( *(int*)a - *(int*)b ); } int main () { int n; qsort (values, 6, sizeof(int), compare); for (n=0; n<6; n++) printf ("%d ",values[n]); return 0; }
Le problème de cette approche (mais qui est amplement suffisante dans ton cas) c'est qu'elle suppose que l'opérateur "-" a un sens pour les valeurs comparées et que - retourne une valeur nulle en cas d'égalité, négative si a précède b, positive sinon. C'est ce qu'on fait traditionnellement en C. Si on veut trier dans l'autre sens, il faut écrire une autre fonction compare. Ça tombe bien pour des chaînes de caractères, strcmp se comporte exactement comme ça.
Bon maintenant c'est cool, mais ça c'est du C, et à chaque fois que le type de "values" change, on doit réécrire une fonction "compare". Alors voyons comment en C++ on peut faire ça avec n'importe quel type, en supposant que ce type a un opérateur <.
L'idée comme on veut garder les doublons, c'est d'utiliser un multiset (si on voulait dégager les doublons, on utiliserait un set).
http://www.cplusplus.com/reference/set/multiset/
Avant rentrer dans le vif du sujet si tu n'as jamais utilisé la STL, je te conseille de lire ceci pour te familiariser avec la notion de container et d'iterator :
https://forums.commentcamarche.net/forum/affich-37604421-introduction-a-la-stl-en-c-standard-template-library
Revenons à ton problème. Ce premier programme montre comment on insère les valeurs stockées dans "values" dans deux multisets, l'un triant par ordre croissant, l'autre dans l'ordre décroissant.
#include <set> #include <iostream> template <typename Key, typename Compare, typename Alloc> std::ostream & operator << ( std::ostream & out, const std::multiset<Key, Compare, Alloc> & s ){ out << '{'; typename std::multiset<Key, Compare, Alloc>::const_iterator sit (s.begin()), send(s.end()); for(;sit != send; ++sit) out << ' ' << *sit; out << " }"; return out; } int main() { typedef int value_t; const std::size_t n = 6; value_t values[n] = {1, 5, 4, 3, 8, 4}; std::multiset<value_t> s_increasing; std::multiset<value_t, std::greater<value_t> > s_decreasing; for(std::size_t i = 0; i < n; ++i) { s_increasing.insert(values[i]); s_decreasing.insert(values[i]); } std::cout << "s_increasing = " << s_increasing << std::endl << "s_decreasing = " << s_decreasing << std::endl; return 0; }
Résultat :
s_increasing = { 1 3 4 4 5 8 } s_decreasing = { 8 5 4 4 3 1 }
Détaillons un peu le code.
Le code de l'opérateur << est juste là pour écrire facilement un mutliset dans un flux, l'intérêt du programme réside dans ton cas surtout dans la partie où l'on déclare s_increasing et s_decreasing.
Si tu as pris le temps de regarder le lien ci-dessus, tu verras que pour un multiset les paramètres template Compare et Alloc sont optionnels. Dans le code ci-dessus je me suis reposé la dessus :
- dans la déclaration de s_increasing j'ai omis les paramètres template Compare (qui prend donc pour valeur par défaut std::less<value_t>, donc un tri effectué selon l'opérateur <) et Alloc ;
- dans la déclaration de s_decreasing j'ai précisé l'ordre (qui repose pour le coup sur l'opérateur >).
Revenons sur <<. Tu vois que l'on itère sur chaque valeur contenu dans un multiset générique et qu'on écrit les valeurs rencontrées dans un flux de sortie. Bon c'est bien tout ça mais j'imagine que maintenant, ce que tu veux, c'est stocker les valeurs triées dans un tableau (que je vais nommer "triees" dans ce qui suit). C'est ce que va faire ma fonction order_values :
- elle lit un tableau de taille n nommé "in"
- elle répercute le contenu dans un tableau de taille n nommé "out"
Évidemment je veux me laisser la possibilité d'ordonner selon différents foncteurs Compare (le mot est lâché), pas seulement std::less. Ça va donc être un paramètre template de ma fonction. Comme je veux pouvoir trier n'importe quel tableau de valeur (par exemple T = int, T= double, ou T = ma_classe) c'est aussi un paramètre template.
#include <set> #include <ostream> #include <iostream> template <typename T, typename Compare> void order_values( const T * in, T * out, std::size_t n ){ std::multiset<T> s; for(std::size_t i = 0; i < n; ++i) { s.insert(in[i]); } typename std::multiset<T>::const_iterator sit (s.begin()), send(s.end()); for(std::size_t i = 0; sit != send; ++sit, ++i) { out[i] = *sit; } } int main() { typedef int value_t; const std::size_t n = 6; value_t values[n] = {1, 5, 4, 3, 8, 4}; value_t triees[n] = {0, 0, 0, 0, 0, 0}; order_values<value_t, std::less<value_t> >(values, triees, n); std::cout << '{'; for(std::size_t i = 0; i < n; ++i) std::cout << ' ' << triees[i]; std::cout << " }"; return 0; }
Sortie :
{ 1 3 4 4 5 8 }
Bonne chance
kratosmindfreak
Messages postés
43
Date d'inscription
mercredi 23 janvier 2013
Statut
Membre
Dernière intervention
1 février 2013
25 janv. 2013 à 19:46
25 janv. 2013 à 19:46
bah tu veux faire un tri d'ordre croissant d'un tableau on utilisant un autre tableau c'est ca ?
si oui donc tu vas creer deux tableau premier tableau contient les valeurs a trier et l'autre pour mettre les valeurs qui soit trier
premierement tu va chercher le min tu peut utiliser une fonction qui s'appelle min
puis tu stocke le min retourner par la fonction min donc le deuxieme tableau puis tu incrementes l'indice de deuxieme tableau
puis tu cherche un autre min qui egal ou superieure au precedente en passant a la fonction min le premier tableau et la valeur min precedent..................
tu repete cette ce traitement n fois(taille de premier tableau)
bah j'ai donner les grands lignes le reste a faire c'est tres simple il faut seulement reflechir un peut
si tu as un autre question ou bien tu pas compris quelque chose envoi moi un message
si oui donc tu vas creer deux tableau premier tableau contient les valeurs a trier et l'autre pour mettre les valeurs qui soit trier
premierement tu va chercher le min tu peut utiliser une fonction qui s'appelle min
puis tu stocke le min retourner par la fonction min donc le deuxieme tableau puis tu incrementes l'indice de deuxieme tableau
puis tu cherche un autre min qui egal ou superieure au precedente en passant a la fonction min le premier tableau et la valeur min precedent..................
tu repete cette ce traitement n fois(taille de premier tableau)
bah j'ai donner les grands lignes le reste a faire c'est tres simple il faut seulement reflechir un peut
si tu as un autre question ou bien tu pas compris quelque chose envoi moi un message
Ratblanc68
Messages postés
4
Date d'inscription
vendredi 25 janvier 2013
Statut
Membre
Dernière intervention
25 janvier 2013
25 janv. 2013 à 20:49
25 janv. 2013 à 20:49
Voilà ça doit être à peu près ça (:
Le problème c'est que je débute en progra et tout ça ne m'est pas très familié.
Donc la fonction min ? Nécéssite t-elle une bibliothèque particulière ? sachant que je dois faire un petit programme en console.
Donc j'ai bien compris ce que tu as dit mais j'ai pas compris un truc, après avoir trouvé la valeur min comment faire pour trouver la "min2" c'est à dire la valeur immédiatement égale ou supérieure à la "min" ?
en utilisant la fonction min, ne risque-je pas de retomber sur la min précédente ?
ex : j'ai les valeurs dans le 1er tableau : 1 5 4 3 8 4
min : 1
2ème tableau : 1 .. .. .. .. .. ..
comment faire pour prendre le 3 maintenant ?
Le problème c'est que je débute en progra et tout ça ne m'est pas très familié.
Donc la fonction min ? Nécéssite t-elle une bibliothèque particulière ? sachant que je dois faire un petit programme en console.
Donc j'ai bien compris ce que tu as dit mais j'ai pas compris un truc, après avoir trouvé la valeur min comment faire pour trouver la "min2" c'est à dire la valeur immédiatement égale ou supérieure à la "min" ?
en utilisant la fonction min, ne risque-je pas de retomber sur la min précédente ?
ex : j'ai les valeurs dans le 1er tableau : 1 5 4 3 8 4
min : 1
2ème tableau : 1 .. .. .. .. .. ..
comment faire pour prendre le 3 maintenant ?
Ratblanc68
Messages postés
4
Date d'inscription
vendredi 25 janvier 2013
Statut
Membre
Dernière intervention
25 janvier 2013
25 janv. 2013 à 22:23
25 janv. 2013 à 22:23
Eh bien merci en tout cas pour ton aide mais malheureusement, novice que je suis je n'ai toujours pas réussi à faire fonctionner ce programme malgré toute ma bonne volonté.
voici l'intégralité de mon programme :
Donc je le lance :
alors avec tailleTab = 10 et valMax= 10
j'obtiens en 1er tableau (aléatoire) = 3 8 9 7 1 3 2 10 4 7
mais en 2ème tableau j'obtiens malheureusement pas du tout ce que je voudrai ):
2ème tableau = 000 0 0 0 0 0 0 0 0 0 (voilà exactement ce que j'obtiens)
Bon je suis convaincu que j'ai fait n'importe quoi mais ça commence à m'embêter ): je ne sais pas du tout quoi faire, si tu pouvais encore me venir en aide, ou quelqu'un d'autre
voici l'intégralité de mon programme :
#include <iostream> #include <cstdlib> #include <time.h> #include <windows.h> using namespace std; int min(int *tab,int x,int n) { int i,min; min=x; for(i=0;i<n;i++) if(tab[i]<min)min=tab[i]; return min; } int main() { int tailleTab,valMax,i,valMin; cout << "Taille du tableau : "; cin >> tailleTab; int Tab1[tailleTab]; cout << "Valeur maximale : "; cin >> valMax; cout << "Valeurs non triées :"; srand(time(NULL)); for (i=0;i<tailleTab;i++) { Tab1[i]= rand()%valMax+1; cout << Tab1[i] << " "; } int Tab2[tailleTab]; valMin=valMax; for (i=0;i<tailleTab;i++) { if (Tab2[i]<valMin) valMin = Tab2[i]; } cout << "min = " << valMin; Tab2[0]=valMin; cout << Tab2[0]; for (i=0;i<tailleTab;i++) { Tab2[i]=min(Tab1,Tab2[0],tailleTab); cout << Tab2[i]<<" "; } return 0; }
Donc je le lance :
alors avec tailleTab = 10 et valMax= 10
j'obtiens en 1er tableau (aléatoire) = 3 8 9 7 1 3 2 10 4 7
mais en 2ème tableau j'obtiens malheureusement pas du tout ce que je voudrai ):
2ème tableau = 000 0 0 0 0 0 0 0 0 0 (voilà exactement ce que j'obtiens)
Bon je suis convaincu que j'ai fait n'importe quoi mais ça commence à m'embêter ): je ne sais pas du tout quoi faire, si tu pouvais encore me venir en aide, ou quelqu'un d'autre
25 janv. 2013 à 22:30
Je n'ai même pas lu toute l'intégralité de ton post que je sais déjà que cela va me permettre d'aboutir enfin à quelque chose, merci beaucoup !
25 janv. 2013 à 22:37