2011-10-15 36 views
5

Tengo un conjunto de datos que en alguna ocasión necesito ordenarlos de una manera u otra en otra. Por ejemplo, supongamos que el conjunto de datos es un conjunto de cadenas, {"abc", "dfg", ...}. A veces tengo que ordenarlos en orden alfabético y, a veces, comparando su longitud.¿Es posible cambiar el comparador de un C++ std :: set?

Inicialmente usé std :: set como contenedor de mis datos e implementé 2 comparadores, con la esperanza de poder cambiar el comparador sobre la marcha, porque la información es enorme y no es una buena idea copiarla de un conjunto a otro ... Solo quiero ordenarlo usando diferentes comparadores de vez en cuando. ¿Es esto posible o cuál es la forma correcta de hacerlo?

Respuesta

6

Debe especificar el comparador de std::set en el momento de la construcción.

Como solución, mantendría dos conjuntos de 'índices' en su lugar, cada uno haciendo referencia a la colección real. Esto daría la mayor flexibilidad. Para mantener todo junto, le sugiero que lo envuelve en una sola clase:

// to be compiled, debugged etc..., but ideal 
// to grab the idea 
// caveats: maintain the index objects whenever the collection 
// gets resized/reallocated etc... 
// so not to be written yourself, use an existing library :) 
template< typename T, typename comp1, typename comp2 > 
struct MultiIndex { 
    std::deque<T> collection; 
    std::set<T*, comp1> index1; 
    std::set<T*, comp2> index2; 

    void insert(const T& t){ 
     collection.push_back(t); 
     index1.insert(&collection.back()); 
     index2.insert(&collection.back()); 
    } 
}; 

biblioteca Boost tiene tal clase: Multiindex.

+0

Gracias xtofl! Exactamente lo que quiero – blurrcat

2

El conjunto se guarda siempre de forma interna (de lo contrario, no tendría el rendimiento necesario), por lo que no, el comparador no se puede cambiar. Lo que creo que la mejor solución aquí es mantener dos conjuntos con los mismos datos, pero con diferentes comparadores. Encapsularía los dos conjuntos en una clase y las funciones como la inserción funcionarían en ambos conjuntos para garantizar que los datos sean los mismos en ambos conjuntos.

Si no necesita tener los datos ordenados todo el tiempo, otra forma de lograr lo que desea sería simplemente usar, p. un vector y clasifíquelo según el comparador que necesite cuando sea necesario.

1

No, no sobre la marcha. El árbol se construye según los criterios de clasificación especificados en el momento de la construcción. Está hablando de crear múltiples índices en un solo conjunto de datos, lo que podría lograrse con múltiples conjuntos. Probablemente hay muchas librerías como boost que tienen algo ya creado para esto.

Cuestiones relacionadas