2010-04-07 18 views
0

En C++, je cherche à mettre en oeuvre un opérateur pour sélectionner des éléments dans une liste (de type B) sur la base B étant contenu entièrement à l'intérieur A.Modèles et C++ opérateur pour la logique: B contenus dans l'ensemble A

Dans le livre "la conception logique des ordinateurs numériques" par Montgomery Phister jr (publié en 1958), p54, il est dit:

F11 = A + ~ B a deux associations intéressantes et utiles, aucun d'entre eux ayant beaucoup à faire avec la conception d'ordinateur. La première est la notation logique de l'implication ... La seconde est la notation de l'inclusion ... Cela peut être exprimé par une relation d'aspect familier, B < A; ou par l'énoncé "B est inclus dans A"; ou par l'équation booléenne F11 = A + ~ B = 1.

Ma mise en œuvre initiale était en C. Des rappels ont été donnés à la liste à utiliser pour de telles opérations. Un exemple étant une liste d'ints, et une structure contenant deux nombres ints, min et max, à des fins de sélection.

Dans ce cas, la sélection serait basée sur B> = A-> min & & B < = A-> max. En utilisant C++ et les templates, comment approcherais-tu ceci après avoir implémenté une liste générique en C en utilisant des pointeurs et des callbacks void?

Utilise < comme opérateur surchargé à de telles fins ... <ugh> evil? </ugh >

(ou en utilisant une classe B pour les critères de sélection, la mise en œuvre de la comparaison par la surcharge>?)

modifier: ma mise en œuvre des noeuds de la liste contient un membre pour signaler l'article sélection ou non. En ce qui concerne les ensembles, et l'unicité, les données de la liste contiendront probablement un membre spécifiant la position le long d'une ligne de temps, étant donné que l'un des principaux critères de sélection, en utilisant le jeu de termes pourrait être trompeur car il n'y a pas l'unicité garantie en ce qui concerne la position le long de la ligne temporelle - c'est-à-dire que les événements peuvent se produire simultanément.

Répondre

3

La façon dont cela se fait un peu partout dans la bibliothèque standard est deux ont un paramètre basé sur un modèle qui peut prendre une fonction/foncteur et qui est utilisé pour les comparaisons:

template<typename Predicate> 
void container::select(Predicate p) { 
    if (p(items[0])) { 
    // something 
    } 
} 

Quelques exemples de la norme bibliothèque serait remove_if ou lower_bound.

(Il faut aussi savoir qu'il existe déjà un modèle de classe set dans la bibliothèque standard, et des algorithmes comme set_intersection)

+0

+1 pour set_intersection.Les algorithmes de la bibliothèque standard sont trop souvent ignorés et pourtant, il y en a souvent un qui convient parfaitement à ce que vous essayez d'accomplir. –

+0

peut-être que mon utilisation du jeu de termes était erronée dans ce cas, la liste ne contient pas nécessairement des éléments uniques (où l'unicité est basée sur ce qui est sélectionné par). –

+0

accepté pour mentionner les foncteurs - pensait encore en termes de pointeurs de fonction. –

0

OMI, en utilisant « < » serait mal. S'il ne calcule pas "moins que", c'est probablement une mauvaise utilisation.

Dans ce cas, je modéliserais mon implémentation après STL. Je ne suis pas sûr que ce soit exactement ce que vous êtes après, et il est non testé, mais:

Edit: compilé & testé:

#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <iterator> 
#include <functional> 
#include <ext/functional> 

using namespace std; 
using __gnu_cxx::compose2; 

int main(int argc, char** argv) { 
    vector<int> list_of_b; 
    vector<int> included_in_a; 

    int min = 2; 
    int max = 5; 
    remove_copy_if(list_of_b.begin(), list_of_b.end(), 
       back_inserter(included_in_a), 
       not1(compose2(logical_and<bool>(), 
           bind2nd(greater<int>(), min), 
           bind2nd(less<int>(), max)))); 
    copy(included_in_a.begin(), included_in_a.end(), 
     ostream_iterator<int>(cout, "\n")); 
    return 0; 
} 
+0

Ce n'est pas exactement ce que je suis après non, mais je n'ai pas mentionné la classe que j'utilise pour les noeuds dans la liste a un membre pour marquer si un élément est sélectionné ou non (vous pouvez sélectionner des éléments sans les supprimer). –