12
votes

Tri des ensembles utilisant STD :: Trier

J'aimerais savoir si nous pouvons trier un ensemble pré-créé. Lorsque je crée d'abord le jeu S_P2, je trie à l'aide d'un élément d'élément différent. Longueur (). Mais après l'entrée de l'utilisateur, je voudrais trier les éléments en fonction de la valeur X Point.get (). Comment je fais cela?

Il semble que le conteneur défini n'a pas de fonction de tri. Et on me conseille d'utiliser le vecteur. Mais les ensembles sont capables de stocker uniquement des éléments uniques.

Q1: Comment puis-je trier un ensemble en fonction des critères

Q2: Si l'ensemble est incapable de le faire que quel conteneur STL est le meilleur choix et comment puis-je trier les éléments du conteneur.


0 commentaires

3 Réponses :


9
votes

std :: set stocke ses membres de manière triée. Si vous parcourez le jeu de .begin () à .end () , vous aurez une liste triée d'éléments.

Si vous n'aimez pas les critères de tri par défaut, vous pouvez fournir un paramètre de modèle 2ème modèle à STD :: SET <>


3 commentaires

Yup .. je comprends. mais puis-je re-trier


@ user1571494 - Non, vous ne pouvez pas le résoudre. Vous peut copier les éléments de ce std :: set <> et dans un conteneur différent - peut-être un std :: set avec un paramètre de modèle de comparaison différent.


Je crois que les ensembles acceptent un comparateur ou un objet (soit à un pointeur à une fonction ou à une classe avec un opérateur d'appel de fonction) capable de prendre 2 objets dans l'ensemble et de déterminer un ordre absolu entre eux. Si vous regardez l'exemple au bas de cette page: Cplusplus.com/reference/ STL / SET / SET , il existe un exemple d'un ensemble avec un comparateur personnalisé.



17
votes

Vous ne pouvez pas recourir à un jeu , comment il trie fait partie du type du fichier SET . Un fichier donné a une commande définie fixe qui ne peut pas être modifiée.

Vous pouvez créer un nouveau définir avec les mêmes données relativement facilement. Il suffit de créer un nouveau jeu qui est basé sur les nouveaux critères.

Si vous souhaitez utiliser les deux SET S dans le même code, vous devez abstrumer l'accès au paramètre sous-jacent .

Maintenant, si vous faites des lectures et des modifications rares, en utilisant un vecteur que vous triez manuellement est souvent une meilleure idée. Vous pouvez supprimer des duplicats en utilisant le std :: unique - efface idiom.


4 commentaires

Vector est ok avec moi. Mais je ne suis pas sûr de savoir comment mettre en œuvre la STD :: Effacer unique. Pouvez-vous conseiller?


@ user1571494: donné un vecteur trié, v.térase (std :: unique (v.begin (), v.end (), v.end ()); supprimera des doublons.


Notez que le code ci-dessus @Mike a écrit utilisera opérateur == pour les comparer. Vous devrez peut-être passer dans un prédicat pour que vous ne puissiez que des choses nucives équivalentes (! (A


Notez également que ne manquez pas ce dernier , v.end () - il compilera, mais ne fera rien de sensibilité, mais peut passer quelques tests manuels.



3
votes

Vous pouvez avoir deux ensembles et les conserver en synchronisation ou en copier un à l'autre.

#include <iostream>
#include <set>

using namespace std;

struct AB
{
   AB(int a,int b) : _a(a),_b(b) {}

   int _a;
   int _b;
};

struct byA
{
    bool operator () (const AB& lhs, const AB& rhs)
    {
          return lhs._a <= rhs._a;
    }
}; 

struct byB
{
    bool operator () (const AB& lhs, const AB& rhs)
    {
       return lhs._b <= rhs._b;
    }
}; 

typedef set<AB,byA> ByA;
typedef set<AB,byB> ByB;
typedef ByA::const_iterator ByAIt;
typedef ByB::const_iterator ByBIt;

void getByB(const ByA &sA,ByB &sB)
{
   for(ByAIt iter=sA.begin(); iter!=sA.end();++iter) {
      const AB &ab=*iter;
      sB.insert(ab);
   }
}

int main(int argc, const char **argv)
{
   ByA sA;
   sA.insert(AB(3,6));
   sA.insert(AB(1,8));
   sA.insert(AB(2,7));

   ByB sB;
   getByB(sA,sB);

   cout << "ByA:" << endl;
   for(ByAIt iter=sA.begin(); iter!=sA.end();++iter) {
      const AB &ab=*iter;
      cout << ab._a << "," << ab._b << " ";
   }
   cout << endl << endl;

   cout << "ByB:" << endl;
   for(ByBIt iter=sB.begin(); iter!=sB.end();++iter) {
      const AB &ab=*iter;
      cout << ab._a << "," << ab._b << " ";
   }
   cout << endl;
   return 0;
}


0 commentaires