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

 C++ Discussion :

Vérifier que toutes les valeurs d'un tableau 2D sont uniques


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2013
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 15
    Par défaut Vérifier que toutes les valeurs d'un tableau 2D sont uniques
    Bonjour,

    Je bute depuis un moment sur l'algorithme qui me permettra de vérifier qu'un tableau 2D ne comporte que des chiffres uniques. J'ai eu un élan d'inspiration qui s'est vite estompé, je vous l'écris :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
       int chiffreTeste;
       for(int idLig = 0; idLig < TailleTableau2D; idLig++){
          chiffreTeste = idLig;
          for(int idCol = 0; idCol < TailleTableau2D; idCol++){
             if(idLig == idColà){
                continue;
             }
             if(tableau2D[idLig][idCol] == chiffreTest){
                cout << "Le tableau ne comporte pas que des valeurs uniques";
                break;
             }
          }
       }
    Je me suis très vite rendu compte que ma variable chiffreTeste s'incrémentait à chaque tour de boucle et que par conséquent je n'effectue le test de chiffreTeste que sur une ligne et non sur le tableau entier.

    Quelques conseils ?

    Merci à vous

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Par défaut
    A ma connaissance on ne peut pas le faire directement avec la STL, mais c'est tout comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::vector<int> vec ( tableau2D, tableau2D + TailleTableau2D );
    std::sort( vec.begin(), vec.end() );
    auto it = std::adjacent_find(vec.begin(), vec.end());
    assert ( it == vec.end() );
    Ou plus fourbe encore :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    std::set<int> s( tableau2D, tableau2D + TailleTableau2D );
    assert ( s.size() == TailleTableau2D );
    Après, il y a sûrement plus optimal.

  3. #3
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Citation Envoyé par cob59 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::set<int> s( idLig, idLig + TailleTableau2D );
    assert ( s.size() == TailleTableau2D );
    Intuitivement je serai parti la dessus.

    Les deux solutions que tu proposes sont en O(n * log n).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::unordered_set<int> s( idLig, idLig + TailleTableau2D );
    assert ( s.size() == TailleTableau2D );
    Devrait être meilleur pour de grands tableaux (O (n)).
    Pour de petits tableaux, il faudrait tester pour voir ce qui est le meilleur.

    Si le tableau est déjà trié, alors un std::adjacent_find est clairement la meilleure solution (O(n)).

    edit: à adapter si la mémoire du tableau 2D n'est pas consécutive. Il faut dans ce cas faire nbLignes (ou nbColonnes) insertions.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Si tu es en C++11 tu as accès à
    http://www.cplusplus.com/reference/algorithm/any_of/
    http://www.cplusplus.com/reference/algorithm/all_of/
    http://www.cplusplus.com/reference/algorithm/none_of/
    Sinon, tu peux toujours ruser avec
    http://www.cplusplus.com/reference/algorithm/find_if/

    Si tu veux les réimplémenter c'est assez trivial, et tu peux par exemple utiliser l'exemple Python pour te rendre compte d'où mettre tes return en particulier
    http://docs.python.org/2/library/functions.html#all
    http://docs.python.org/2/library/functions.html#any
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Février 2013
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 15
    Par défaut
    Bonjour,

    Merci à vous pour vos réponses. J'ai entre temps réalisé un code qui semble fonctionner. Je vais étudier vos solutions un peu plus en détail car je n'ai pas encore le niveau nécessaire en c++ me permettant de les utiliser sans me poser de questions.

    Pour ma part j'ai réalisé le code suivant (je ne recherche pas actuellement le code le plus optimisé, je cherche juste une solution qui marche, après quoi je vois si je peux faire quelque chose).

    Code : 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
     
       if(ok){
     
          for(int iTest = 0; iTest < tailleCarre; iTest++){
             if(ok == false){
                break;
             }
             for(int jTest = 0; jTest < tailleCarre; jTest++){
                if(ok == false){
                   break;
                }
                int chiffreTeste = carreMagique[iTest][jTest];
                for(int idLig = 0; idLig < tailleCarre; idLig++){
                   if(ok == false){
                      break;
                   }
                   for(int idCol = 0; idCol < tailleCarre; idCol++){
                      if(idCol == jTest){
                         continue;
                      }
                      if(carreMagique[idLig][idCol] == chiffreTeste){
                         ok = false;
                         cout << "no !" << endl;
                         cout << carreMagique[idLig][idCol] << ' ' << chiffreTeste;
                         break;
                      }
                   } 
                }
             }
          }   
       }
    C'est très moche je vous l'accorde mais ça semble fonctionner. J'étudie de ce pas vos solutions !

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Tous ces if(ok) sont vraiment très moches et je comprends pas comment un esprit logique peut arriver à ça
    alors qu'il suffit de placer un return false au milieu et un return true tout en bas.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Si tu stockais ton tableau 2D comme un tableau aplati, comme cela est souvent recommandé, tu pourrais utiliser std::unique_copy, puis comparer sa longueur avec celle du tableau original.

  8. #8
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 527
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 527
    Par défaut
    je suis d'accord avec Bousk c'est mal programmé
    J'ai lu rapidement le code une fonction récursive serait peut-être plus appropriée

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 02/08/2011, 13h50
  2. Réponses: 6
    Dernier message: 12/01/2010, 15h39
  3. Vérifier que toutes les balises soient bien fermées dans le bon ordre
    Par piotrr dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 19/02/2009, 10h32
  4. [MySQL] Requête pour récupérer toutes les valeurs d'un tableau
    Par djoumusic dans le forum PHP & Base de données
    Réponses: 40
    Dernier message: 24/08/2008, 22h11
  5. initialiser toutes les valeurs d'un tableau
    Par Biosox dans le forum C++
    Réponses: 1
    Dernier message: 09/11/2007, 10h41

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