Partage
  • Partager sur Facebook
  • Partager sur Twitter

std::vector et sort

    2 novembre 2018 à 6:56:07

    bonjour a tous, j'aimerai trier un un tableau dans un std::vector<player>. Je ne sais pas vraiment comment m'y prendre pour trier avec number.

    struct card
    {
    	std::string str;
    	int number;
    };
    
    struct player
    {
    	card list[5];
    };



    -
    Edité par JEANBAPTISTECOMTE1 2 novembre 2018 à 6:59:09

    • Partager sur Facebook
    • Partager sur Twitter
      2 novembre 2018 à 9:56:01

      Un premier point, si tu n'as que 5 cartes (et toujours 5 cartes) par joueur, le mieux est de définir ta structure ainsi:

      #include<array>
      
      struct Player
      {
         std::array<card,5> list;
      };

      Ca t'évitera des boulettes car std::array connaît sa taille, donc le compilateur pourra détecter une éventuelle erreur de débordement.

      Si le joueur peut avoir des mains de taille différentes utilise plutôt std::vector, lui aussi connaît sa taille, le runtime debug pourra le cas échéant détecter une boulette.

      Pour le problème du tri, il y a un problème, il te faut définir un critère de tri strict (éventuellement préfère std::stable_sort à std::sort, il est moins strict, il est capable de se débrouiller avec des éléments "équivalents"). Le soucis, c'est comment tu compare deux tableaux de 5 card?

      On pourrait dire que la valeur du tableau est égale à la somme des number, ou à la moyenne, ou au minimum, maximum, ou n'importe quel autre critère.

      Par exemple pour le max

      #include<array>
      #include<limits>
      
      struct Player
      {
         std::array<card,5> list;
      
         int max() const{
           int value{std::numeric_limits<int>::min()};
           for (auto const & c : list){
              if (c.number > value){
                 value = c.number;
              }
           }
           return value;
         }
      };
      
      std::vector<player> players;
      
      std::stable_sort(std::begin(players),std::end(players),
                      [](Player const & lhs,Player const & rhs)
                         {return lhs.max() > rhs.max();});



      • Partager sur Facebook
      • Partager sur Twitter
      Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
        2 novembre 2018 à 23:39:11

        Merci int21h pour cet exemple parlant

        voici un autre exemple d'utilisation de sort en bas sur la page avec les foncteurs :

        https://openclassrooms.com/fr/courses/1894236-programmez-avec-le-langage-c/1903389-la-puissance-des-algorithmes

        -
        Edité par pseudo-simple 2 novembre 2018 à 23:39:30

        • Partager sur Facebook
        • Partager sur Twitter
          4 novembre 2018 à 4:12:03

          Les foncteurs étant plutôt un choix illogique quand on a accès aux lambdas.
          • Partager sur Facebook
          • Partager sur Twitter
            5 novembre 2018 à 11:12:06

            YES, man a écrit:

            Merci int21h pour cet exemple parlant

            voici un autre exemple d'utilisation de sort en bas sur la page avec les foncteurs :

            https://openclassrooms.com/fr/courses/1894236-programmez-avec-le-langage-c/1903389-la-puissance-des-algorithmes

            Arrête de faire des références à ce cours obsolète.

            • Partager sur Facebook
            • Partager sur Twitter

            git is great because Linus did it, mercurial is better because he didn't.

              5 novembre 2018 à 12:45:04

              markand a écrit:

              Arrête de faire des références à ce cours obsolète.

              Pour préciser ce qui ne va pas dans ce chapitre :

              - utilisation de using namespace std (encore et toujours)

              - on va preferer std::begin et std::end plutot que les fonctions membres

              - on va preferer auto plutot qu'ecrire explicitement le type iterator

              - on va utiliser des fonctions lambdas plutot que des classes foncteurs

              - utilisation de rand

              - utilisation de 0 au lieu de nullptr

              - utiliser un range-for loop plutot qu'un for avec un indice

              Je n'ai pas relu le texte, il y a peut etre d'autres problèmes. Mais bon, ce n'est pas le pire chapitre (il est obsolète, mais je n'ai pas vu d'erreur apres une lecture rapide)

              -
              Edité par gbdivers 5 novembre 2018 à 12:45:28

              • Partager sur Facebook
              • Partager sur Twitter
                5 novembre 2018 à 14:54:18

                gbdivers a écrit:

                - on va preferer std::begin et std::end plutot que les fonctions membres

                Quand tu parles de fonction membre, tu parles de "std::begin(vector)" au lieu de "vector.begin()"? Si oui, c'est quoi la difference?


                • Partager sur Facebook
                • Partager sur Twitter

                Eug

                  5 novembre 2018 à 15:11:26

                  Oui.

                  Pour std::vector, aucune différence.

                  std::begin/std::end sont plus facilement adaptables sur n'importe quelles types, simplement en proposant de specialisation template spécifiques. Cela fonctionne avec les conteneurs de la lib standard bien sur, qui proposent deja les fonctions membres begin/end, mais egalement avec des types qui n'ont pas ete prévu a l'origine pour fonctionner avec begin/end (par exemple des tableaux C ou des tableaux d'autres libs).

                  C'est juste une question de recommendations, pour avoir une syntaxe homogène (utiliser partout std::begin/std::end plutot que de dépendre du type de collection).

                  Un exemple concrèt :

                  #include <vector>
                  #include <algorithm>
                  
                  template<typename ARRAY>
                  void sort(ARRAY& array) {
                      std::sort(array.begin(), array.end());
                  }
                  
                  template<typename ARRAY>
                  void sort2(ARRAY& array) {
                      std::sort(std::begin(array), std::end(array));
                  }
                  
                  int main() {
                      std::vector<int> v1 = { 1, 5, 2, 4, 3 };
                      int v2[5] = { 1, 5, 2, 4, 3 };
                  
                      sort(v1);
                      // sort(v2); // error
                  
                      sort2(v1);
                      sort2(v2);
                  }
                  

                  On gagne en maintenabilité du code. (Et accessoirement, on evite de trop penser en termes de "tout OO")

                  -
                  Edité par gbdivers 5 novembre 2018 à 15:12:01

                  • Partager sur Facebook
                  • Partager sur Twitter
                    5 novembre 2018 à 15:17:00

                    Plus de détails: https://linuxfr.org/news/cpp17-libere-size-data-et-empty
                    • Partager sur Facebook
                    • Partager sur Twitter
                    C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.

                    std::vector et sort

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown