2012-03-27 18 views
6

मैंLINQ, एक संग्रह का अनूठा संग्रह बनाने

class Vertex{ 
    Graph _graph; 
    float x; 
    float y; 
    string key; 
    //and some similar atributes 
    public IEnumerable<Edge> Edges{ 
     get{ 
      return _graph.Edges.Where(s => s.Source == this); 
     } 
    } 
} 
class Edge{ 
    Graph _graph; 
    Vertex source; 
    Vertex target; 
} 
class Graph 
{ 
    private VertexCollection _vertexCollection; // extends List<Vertex> 
    private EdgeCollection _edgeCollection; //extends List<Edge> 
    public IEnumerable<Vertex> Vertexes 
    { 
     get 
     { 
      return _vertexCollection; 
     } 
    } 
    public IEnumerable<Edge> Edges 
    { 
     get 
     { 
      return _edgeCollection; 
     } 
    } 
    public IDictionary<Edge, bool> DrawableEdges 
    { 
     get 
     { 
      //want to return my uniq dictionary 
     } 
    }  

Edges और Vertexes सूचियों

कुछ उदाहरण में एकत्र कर रहे हैं:

A-->B // edge from vertex A to B 
B-->C // edge from vertex B to C 
C-->A // edge from vertex C to A 
A-->C // edge from vertex A to C -- this is two way edge 

तो मैं IDictionary<Edge, bool> करना चाहते हैं जो होगा किनारों को पकड़ें (ए -> बी और बी -> ए 1 की तरह होगा), और बूल - यदि यह दो तरह या नहीं है।

मुझे इसकी आवश्यकता है क्योंकि जब मैं उन्हें अब खींचता हूं, तो यह एक दूसरे के नीचे 2 तीर खींचता है। मैं बेहतर 1 तीर बनाना होगा।

तो मैं यहां बहुत फंस गया हूं ... क्या कोई मेरी मदद कर सकता है?

+1

के साथ अपने HashSet प्रारंभ एज की परिभाषा और वर्टेक्स कक्षाएं दिखाने कृपया – sll

उत्तर

2

मुझे लगता है कि आप अपने Edge वर्ग के लिए IEquatable इंटरफ़ेस को लागू करना चाहिए:

public class Edge : IEquatable<Edge> 
{ 
    ... 

    public bool Equals(Edge other) 
    { 
     return (
      (other.Source == this.Source && other.Target == this.Target) || 
      (other.Target == this.Source && other.Source == this.Target)); 
    } 

    public override int GetHashCode() 
    { 
     return (Source.GetHashCode()^Target.GetHashCode()); 
    } 
} 

और एक HashSet<Edge> संग्रह करने के लिए अपने किनारों जोड़ें। फिर आप Contains विधि को यह जांचने के लिए कॉल कर सकते हैं कि इसमें किनारे हैं या नहीं।

संपादित करें: जैसे हेंक कहा, आप भी एक कस्टम IEqualityComparer वर्ग को लागू कर सकते हैं:

public sealed class EdgeComparer : IEqualityComparer<Edge> 
{ 
    public static EdgeComparer Default { get; private set; } 

    static EdgeComparer() 
    { 
     Default = new EdgeComparer(); 
    } 

    private EdgeComparer() 
    { 
    } 

    public bool Equals(Edge x, Edge y) 
    { 
     return (
      (x.Source == y.Source && x.Target == y.Target) || 
      (x.Target == y.Source && x.Source == y.Target)); 
    } 

    public int GetHashCode(Edge edge) 
    { 
     return (edge.Source.GetHashCode()^edge.Target.GetHashCode()); 
    } 
} 

और

_drawableEdges = new HashSet<Edge>(EdgeComparer.Default); 
+0

विचार चाहिए या एक ही तर्क करने के लिए एक अलग तुलनाकर्ता लिखें। हैशकोड –

+0

को गठबंधन करने के लिए एक सममित तरीका भी प्रदान करें, आप 'NaN' समस्याओं से बचने के लिए' बराबर 'के साथ '==' को प्रतिस्थापित करना चाहेंगे। और निश्चित रूप से ओपी को 'बराबर', '==', '! =' और 'GetHashCode()' – CodesInChaos

+1

@ हेनकहोल्टरमैन ट्रू को लागू करने की आवश्यकता है, मैंने GetHashCode() को भी जोड़ा है। –

2

मुझे लगता है कि आपकी एज क्लास में एक कन्स्ट्रक्टर है जो 2 वर्टेक्स लेता है। संभावित विचार के लिए नीचे देखें (मैंने इसे संकलित नहीं किया है, लेकिन उम्मीद है कि आपको विचार मिल जाएगा)।

foreach(Edge edge in Edges) 
{ 
    Edge edge2 = new Edge(edge.V2, edge.V1); 
    if (!dict.ContainsKey(edge) && !dict.ContainsKey(edge2)) 
    { 
     dict[edge] = false; // first time we've seen this edge, so put it in dictionary 
    } 
    else if (!dict.ContainsKey(edge) && dict.ContainsKey(edge2)) 
    { 
     dict[edge2] = true; // a bidirectional edge 
    } 
} 
+0

दस सेकंड तेज मेरे से ड्रॉ पर, एक अपवित्र है। –

+0

ye, basicley मुझे केवल – Wish

संबंधित मुद्दे