IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Algorithmes et structures de données Discussion :

Mélange d'un tableau dans tous les ordres possibles


Sujet :

Algorithmes et structures de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Par défaut Mélange d'un tableau dans tous les ordres possibles
    Bonjour.

    Je travaille en C++ et mon problème est le suivant :

    D'un côté, j'ai un tableau de référence tabref remplis d'éléments tous différents.

    De l'autre j'ai une fonction qui prend un tableau en paramètre et qui effectue un certain nombre d'opérations.

    Ce que je cherche à faire c'est exécuter cette fonction pour tous les arrangements possibles (ordre des éléments) du tableau tabref.

    Comment faire cela le plus simplement possible ?

    Merci beaucoup

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 59
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 415
    Par défaut
    Bonjour,

    Une démarche peut être la suivante :
    - Implémentation récursive
    - Utilisation d'une continuation (pointeur sur fonction, ou instance implémentant une méthode)

    Deux fonctions sont à définir :
    - Le point d'entrée de la récursion :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Initialisation d'un tableau indiquant les valeurs déjà utilisées
    Initialisation d'un tableau qui contiendra le résultat
    Appel de la fonction récursive avec un niveau 0 en paramètre
    - La fonction récursive :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Si le niveau = la taille du tableau alors appeler la continuation
    Sinon,
         Boucler sur les indices du tableau
              Si la valeur n'est pas déjà utilisée
                   Marquer la valeur comme utilisée
                   Assigner la valeur dans le résultat
                   Appeler la fonction récursivement avec le niveau + 1
                   Marquer la valeur comme non utilisée
    En C#, ça donne ça (j'ai tout oublié de mon c++... désolé... mais j'ai mis plein de commentaires pour aider à la transposition) :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    // list = ton tableau d'origine
    // action = la continuation (en c++ implémenter sous forme d'un pointeur sur fonction ou passer un objet portant une méthode définie pour traiter les résultats
    public static void Arrangement<T>( List<T> list, Action<IEnumerable<T>> action )
    {
        // Initialisation d'un tableau de flag (false = non encore utilisé, true = déjà utilisé)
        // Ici, à l'allocation, tout est false par défaut
        bool[] flags = new bool[list.Count];
        // Le tableau qui va contenir le résult (il fait la taille du tableau d'origine)
        T[] result = new T[list.Count];
     
        // Appel de la fonction récursive avec tout ça et au niveau 0
        Arrangement( list, flags, result, 0, action );
    }
     
    static void Arrangement<T>( List<T> list, bool[] flags, T[] result, int level, Action<IEnumerable<T>> action )
    {
        // Si le niveau = taille du tableau, alors on a fini
        if ( level == list.Count )
        {
            action( result );
        }
        else
        {
            // Boucle sur toutes les positions
            for ( int i = 0 ; i < list.Count ; i++ )
            {
                // Si pas déjà utilisé
                if ( flags[i] == false )
                {
                    // Marquer comme utilisé
                    flags[i] = true;
                    // Mettre le résultat à sa position
                    result[level] = list[i];
     
                    // Appel récursif
                    Arrangement( list, flags, result, level + 1, action );
     
                    // Enlever le marquage
                    flags[i] = false;
                }
            }
        }
    }


    Une implémentation récursive pour ce type de problème est souvent plus efficace qu'une implémentation itérative, car elle utilise peu de mémoire.

    L'utilisation d'une continuation permet de ressortir simplement les résultats (pas besoin de "retourner" les résultats, on les exploite dès qu'on les a).

    Mais attention le nombre d'arrangements grimpe très vite ! Donc sur des tableaux un peu grands, ça va prendre du temps de calcul !!

  3. #3
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 54
    Par défaut
    Essaie next_permutation. La STL le fait pour toi moyennant la comparaison ;-)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 23
    Dernier message: 11/04/2006, 17h33
  2. Réponses: 2
    Dernier message: 07/03/2006, 15h27
  3. Réponses: 4
    Dernier message: 01/03/2006, 13h58
  4. Pour qu'un logiciel ne soit utiliser dans tous les sessions
    Par mouloudéen dans le forum Autres Logiciels
    Réponses: 10
    Dernier message: 14/12/2005, 19h10
  5. [MySQL] Rechercher dans tous les champs
    Par Faure dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 05/10/2005, 14h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo