8
votes

Comment trouver un objet avec des valeurs de champ spécifiques dans une STD :: Set?

J'appelle une méthode qui retourne std :: Set const & t est un type de classe. Ce que j'essaie d'atteindre est de vérifier si l'ensemble contient un objet de type t avec des valeurs de champ spécifiques pour une affirmation dans un test automatisé. Cette vérification doit être effectuée pour plusieurs objets.

Voici un exemple simple: Laissez le type t être voiture donc un exemple définir contient un tas de voitures. Maintenant, je veux trouver une voiture avec une couleur spécifique et un nombre spécifique de portes et une vitesse supérieure spécifique dans cet ensemble. Si que la voiture se trouve la première affirmation est vraie et la voiture suivante avec d'autres valeurs de terrain doit être trouvée.

Je ne suis pas autorisé à modifier la mise en œuvre de t . L'utilisation de Boost serait ok.

Comment feriez-vous cela?


2 commentaires

Voulez-vous composer la règle (rouge + Sedan + 200 km / h) au moment de l'exécution? Ou est-ce suffisant de codage dur?


Les règles codées sont suffisantes.


5 Réponses :


0
votes

Vous pouvez essayer un opérateur de dépassement EJ: P>

bool operator<(const Car& a, const Car& b)
{
    return a.color<b.color || (a.color==b.color && a.doors<b.doors) || (a.color==b.color && a.doors==b.doors && a.top_speed<b.top_speed);
}

std::set<Car> cars;
Car x;
cars.find(x);


0 commentaires

1
votes

Face à de tels problèmes, je garde habituellement:

  • A std :: deque ou std :: vecteur de voitures
  • Pour chaque propriété que vous souhaitez rechercher, un std :: multiset des pointeurs vers des voitures, triés par la valeur de la propriété.

    Je cache soigneusement ces conteneurs dans une classe qui me permet d'insérer des voitures.

    L'interface de requête peut varier, mais généralement, vous tirez parti de multiset :: égal_range , std :: Trier et std :: set_intersection .

    Si vous voulez une Volvo rouge quoi que ce soit ... voiture, vous

    1. extrait de égal_range Toutes les voitures rouges, vous donnant une paire itératrice
    2. extrait de égal_range Toutes les voitures Volvo, vous donnant une paire Itératrice
    3. ...
    4. Trier toutes ces gammes par un prédicat commun, disons par adresse du pointeur
    5. Appliquer à plusieurs reprises Set_InterSection dans un std :: deque .

      Un autre moyen est de stocker les voitures dans un deque , de les énumérer et de choisir celui qui répond à toutes vos propriétés, en utilisant std :: Trouver . Cela peut toutefois avoir une complexité pire cependant (cela dépend du nombre de voitures rouges que vous avez pour la naissance)


0 commentaires

17
votes

Cela dépend de la mise en œuvre de t code>. Collons-vous à votre exemple d'une classe voiture code>. Supposons que la classe ressemble à ceci comme ceci:

struct find_by_color {
    find_by_color(const std::string & color) : color(color) {}
    bool operator()(const Car & car) {
        return car.color == color;
    }
private:
    std::string color;
};

// in your code

std::set<Car>::iterator result = std::find_if(cars.begin(), cars.end(), 
                                              find_by_color("green"));
if(result != cars.end()) {
    // we found something
}
else {
    // no match
}


2 commentaires

Ordre lexicographique FTW. Bonne prise. Si vous souhaitez plus de questions générales, mais cela a des limitations (trouvez tous les voitures rouges Volvo)


Utilisez #include pour obtenir la routine STD :: Find_IF.



0
votes

Le STD :: Set vous permet de fournir votre propre fonction de comparaison, comme dans xxx

comparer uniquement les valeurs que vous vous souciez et qu'elles agiront comme si des objets avec ces valeurs sont =. Notez que vous aurez probablement besoin d'un multiset pour cela.

Ce serait le moyen de le faire si vous vous souciez vraiment de la performance de connexion.


0 commentaires

1
votes

Vous voulez std :: recherche_if code>, avec un objet de fonction de prédicat qui vérifie les propriétés qui vous intéressent. Cela pourrait ressembler à ceci:

struct FindCar {
    FindCar(Colour colour, int doors, double top_speed) :
        colour(colour), doors(doors), top_speed(top_speed) {}

    bool operator()(Car const & car) const {
        return car.colour == colour
            && car.doors == doors
            && car.top_speed == top_speed;
    }

    Colour colour;
    int doors;
    double top_speed;
};

std::set<Car> const & cars = get_a_set_of_cars();
std::set<Car>::const_iterator my_car =
    std::find_if(cars.begin(), cars.end(), FindCar(Red, 5, 113));


1 commentaires

Cela défait le but de std :: set , non? std :: Set est capable de trouver des éléments dans o (journal (n)) à l'aide de la recherche binaire. Si vous faites cela, essayez de comprendre comment utiliser std :: Set :: Rechercher ou std :: binaire_search .