2011-12-16 30 views
5

Estoy tratando de escribir un programa en lenguaje C++.Cómo contener mi clase con std :: set

EDGE clase indica la conexión entre u y v.

Edge una que indica la conexión entre u y v. Borde de un' que indica la conexión entre v y u. Edge a y a 'indican la misma conexión. Entonces, quiero contener ya sea a o a '.

Sé que "set" almacena elementos únicos. Entonces quiero usar esto. Defino el operador < a continuación.

Cuando busco errores, encontré algunos trubles. Almacenar (1,2) -> (1,2) -> (2,1) -> (3,2) -> (2,3) -> (5,2).

Pero establecidos tiendas

1 2 
5 2 
3 2 
1 2 <-- Why ???? 

¿podría ayudarme ??

#include<iostream> 
#include<set> 

class Edge { 

private: 
    int u, v; 

public: 
    bool operator< (const Edge& e) const { 
    bool result = true; 
    if((u == e.u && v == e.v) || (v == e.u && u == e.v)) { 
     result = false; 
    } 
    return result; 
    } 

    std::pair<int, int> pair() const { 
    return std::pair<int, int>(u, v); 
    } 

    Edge(int u_, int v_) : u(u_), v(v_) {} 
}; 

int main(void) { 
    std::set<Edge> edge; 
    std::set<Edge>::iterator eit; 

    edge.insert(Edge(1,2)); // <-- (1,2) can be contained. 
    edge.insert(Edge(1,2)); // <-- (1,2) doesn't have to be contained. 
    edge.insert(Edge(2,1)); // <-- (2,2) doesn't have to be contained. 

    edge.insert(Edge(3,2)); // <-- (3,2) can be contained. 
    edge.insert(Edge(2,3)); // <-- (2,3) doesn't have to be contained. 
    edge.insert(Edge(5,2)); // <-- (5,2) doesn't have to be contained. 

    edge.insert(Edge(1,2)); // <-- (1,2) doesn't have to be contained. But edge contains this. Why? 

    for(eit = edge.begin(); eit != edge.end(); eit++) { 

    std::cout << (*eit).pair().first << " " << (*eit).pair().second << std::endl; 
    } 

    return 0; 
} 

Respuesta

5

Su operator< está probando la igualdad, no menos que. Proveedores:

if (u < e.u) 
    result = true; 
else if (e.u < u) 
    result = false; 
else 
    result = (v < e.v); 

Editar: De acuerdo con el comentario no he entendido bien la pregunta - el conjunto se supone que rechazar un duplicado en cualquier orden. El operador de comparación debe ser coherente, así que aquí hay uno que podría funcionar.

if (min(u,v) < min(e.u,e.v)) 
    result = true; 
else if (min(e.u,e.v) < min(u,v)) 
    result = false; 
else 
    result = (max(u,v) < max(e.u,e.v)); 
+0

¡Gracias! Pero, quiero contener uno (1,2) –

+0

@ user975352, 'set' normalmente eliminará duplicados, pero no puede si no define correctamente su operador' <'. –

+1

Esto no es correcto. @ user975352 no quiere (1,2), (2,1) están ambos en el conjunto – Shawnone

3

Usted operator < implementación es más como una implementación de igualdad. trate de hacer léxica menos de aplicación:

bool operator< (const Edge& e) const 
{ 
    return (u < e.u) || (u == e.u && v < e.v); 
} 
0

Su operador < necesita ser refinado. Si no ordena elementos consistentemente, configure y haga mapas de cosas malas.

Trate

bool operator< (const Edge& e) const { 
    return pair() < e.pair(); 
} 
0

Agregar siguiente código antes de su regreso. La razón es contada por otras respuestas.

if(result) 
{ 
    return u < e.u; 
} 
0

usted debe considerar el cambio de su constructor Edge para esto:

Edge(int u_, int v_) : u(u_), v(v_) { if (u>v) swap(u,v); } 

Si se supone que dos bordes a ser "equivalente", entonces puede ser más fácil y menos estresante para grabarlo en un 'canónica 'formato como este.

El otro problema es que está probando la igualdad, no menos que, según lo explicado por otros.

Cuestiones relacionadas