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 33113 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 15 mai 2024 - 25 janv. 2013 à 22:37
Bonsoir, je dois faire un programme en C++ qui range dans l'ordre croissant des valeurs d'un tableau saisi aléatoirement.

Donc voilà, bien sûr je me suis informé, tri à bulle, tri par permutation...

Mais le problème étant que je dois faire un programme qui recherche la valeur minimale du tableau et qui la range dans un autre tableau et ainsi de suite le programme recherche à chaque fois la valeur égale ou immédiatement supérieure à la précédente pour en finalité parvenir à un tri dans l'ordre croissant. Le hic c'est que je n'ai rien vu de tel sur internet et je ne sais pas comment on procède, si vous pouviez me venir en aide, ce serait très aimable parce que je coince.

Merci de votre aide






2 réponses

mamiemando Messages postés 33113 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 15 mai 2024 7 753
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/

#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
1
Ratblanc68 Messages postés 4 Date d'inscription vendredi 25 janvier 2013 Statut Membre Dernière intervention 25 janvier 2013
25 janv. 2013 à 22:30
Woaw, à vrai dire, je n'en attendais pas tant mais mille fois merci
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 !
0
mamiemando Messages postés 33113 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 15 mai 2024 7 753
25 janv. 2013 à 22:37
Parfait alors, mais comme je disais dans mon message tu peux t'arrêter au qsort. Ce qui suit c'est surtout pour ta culture et commencer à découvrir ce qui fait toute la beauté du C++ par rapport au C ;-)
0
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
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
0
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
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 ?
0
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
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 :

#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
0