6
votes

Soustrayez deux commandes sans ordre :: Vecteur d'objets

J'ai deux vecteurs d'objet. Quelque chose comme: xxx

Je veux obtenir un troisième vecteur contenant la Good_things . En d'autres termes, chaque objet de All_thing qui n'appartient pas à Bad_Things : xxx

Toutes idées sur la mise en œuvre Soustraire de manière la plus efficace et la plus standard.

PS Les vecteurs peuvent pas être commandé parce que la classe chose n'a pas toute chose à commander. Merci!

EDIT: et je ne veux pas modifier all_things . e.g. xxx


15 commentaires

Les éléments de vos vecteurs sont-ils uniques?


Pensez à utiliser std :: Set


@Paolom std :: Set nécessite un tri (Ce que les États de l'OP n'est pas possible), il devrait donc utiliser un std: : ONUORDEDED_SET si les éléments sont uniques


Est-ce que chose a un opérateur approprié == ou équivalent?


@Mme. oui c'est unique


Je pense que la classe "chose" devrait avoir une surcharge d'opérateur == comme Andyg suggère que votre code devra vérifier l'équivalence d'objets "truc". La réponse donnée par MKAES ne semble pas compiler non plus, sans la surcharge de l'opérateur. Après avoir ajouté l'opérateur, il devrait s'agir d'une tâche triviale de faire une boucle dans une boucle et de générer le vecteur "Good_things".


J'ai du mal à imaginer quelque chose qui ne peut pas avoir une commande. Si tout le reste échoue, utilisez memcmp avec std :: Trier , puis effacée linéaire.


@NWP: chose de classe {privé: CV :: tapis quelque_photo; } ... bien sûr cv :: mat est quelque chose comme bitmap


Alors, pourquoi ne triez-vous pas chose par les valeurs RVB du bitmap?


Est-ce même un sens? Qu'en est-il du coût?


Vous pouvez avoir confiance memcmp pour être extrêmement bien optimisé. Et chances que vous comparez seulement quelques octets. Si vous pouvez Déplacer chose s efficacité que vous pouvez simplement trier. Sinon, vous pouvez vous assurer de les insérer dans la position correcte lors de la création. Une autre façon serait de garder un vecteur bon; que vous mettez à jour sur chaque insertion / retrait. L'algorithme le plus efficace du Soustraire est de ne pas en avoir besoin, ce qui semble assez faisable.


@nwp Je pense que j'ai mal compris quelque chose.


Une chose peut-elle avoir une commande sans signification, mais logiquement correcte, a-t-elle été ajoutée? Qu'est-ce que == fait à un chose ? Est-il pratique de hacher un chose ? Peut-on ajouter un champ pour cacher le hachage et avoir ce cache être fiable?


Je pense que oui .. Peut-être que ma question est commandée maintenant, ce qui est facile à résoudre. Cependant, je ne veux pas changer cela causer le cas sans commande peut aussi être intéressant!


@Humamhelfawefawi Assurez-vous qu'il est en fait un (total) Commander . Commander Pokemon par type avantage ne fonctionne pas car il n'a pas de commande, mais les commander par alphabet fonctionne. En utilisant aléatoire ne produit pas de commande, à l'aide de memcmp fait. Et bien sûr, vous devez être cohérent et ne pas changer l'ordre.


4 Réponses :


1
votes

Si vous ne pouvez pas les commander, vous pouvez utiliser la force brute. Il suffit de comparer les vecteurs. E.g: xxx


5 commentaires

Pourquoi redimensionnez-vous tout ? Pourquoi laissez-vous les entrées dans la sous-plage [ it , good.end () ) partiellement formé?


+1 Aussi, ne vous sentez pas mal quant à l'utilisation de la force brute avec un std :: vecteur plutôt que d'utiliser un autre conteneur. En fonction de vos circonstances, cela pourrait en réalité être l'approche la plus rapide, grâce au fait que vecteur place ses valeurs dans une seule allocation contiguë.


La dernière ligne ne semble pas fonctionner. Exemple en direct.


Pourquoi est-ce que vous construisez-vous par défaut de sorte que chose s dans bon qui est inutile et évitable?


@Nickyc: parce que c'est un exemple friggin. Vous pouvez simplement utiliser un inserteur du dos et ne pas redimensionner. Cela dépend fortement du cas d'utilisation. Donc, pour la question, c'est plutôt inutile comment vous le faites.



1
votes

Si chose est coûteux à construire / copier et son conteneur est long et les mauvaises sont accablantes, ce n'est pas une bonne idée de construire un même tableau "pas mal". En fait, une matrice de drapeau de tout () x Good.Size () doit être remplie sur la base de la comparaison . Si l'unicité est assurée, il pouvait être épargné par des mauvais méchants. Mais O (n 2 ) est la complexité de toute façon.


0 commentaires

1
votes

Je voudrais suggérer du code similaire à MKAES, mais avec quelques ajustements:

std::vector<thing> substract(const std::vector<thing>& a, const std::vector<thing>& b) {
    std::vector<thing> sub;
    sub.reserve(a.size());
    for (const auto &item : a) {
        if (std::find(b.begin(), b.end(), item) == b.end()) {
             sub.push_back(a);
        }
    }
    return sub;
}


1 commentaires

Améliorer? Peut-être pas, mais cela ne déclenche pas inutilement tout.Size () constructeurs par défaut. Constructeur par défaut pour TYPE n'est même pas obligé d'exister. Il est toujours préférable d'appeler réserve que de déclencher la réaffectation.



2
votes

des commentaires, votre chose s peut être trié, mais de manière inutile.

Et c'est ok.

Triez-les sans signification.

écrire une fonction qui prend deux chose s et donnez-leur un ordre sans signification qui est cohérent et que deux choses ne comparent que non-moins qu'elles sont égales.

appelez ceci bool arb_order_thing (Thing Const &, Thing Const &) .

maintenant std :: Trier Les deux vecteurs et utilisez std :: set_difefence .

Maintenant, cela peut être coûteux si les choses sont coûteuses à copier. Ainsi, créez plutôt deux vecteurs de Const * , écriture bool arb_ordr_thing_ptr (chose const *, chose const *) (qui ne dispose pas de la commande sans signification), triez les vecteurs. -Of-Pointeurs utilisant cela, utilisez Set_Difefence en utilisant cela, puis convertissez-le à un vecteur . .

Alternativement, envisagez d'écrire un Const * hasher (pas un std :: hash , car c'est global et impoli) et utiliser Unommanded_set s pour faire le travail manuellement. Hachage le plus petit des deux vecteurs, puis faire un std :: copy_if testant contre le hachage sur l'autre vecteur.


0 commentaires