2009-06-17 11 views
16

मेरे पास सूची में [x x/x2/x3 "," x1/x2/x4 "," x1/x5 "] जैसे स्ट्रिंग पथ का संग्रह है। मुझे इस सूची से एक वृक्ष जैसी संरचना बनाने की जरूरत है जिसे एक सुंदर मुद्रित पेड़ प्राप्त करने के लिए पुनरावृत्त किया जा सकता है। इस तरहस्ट्रिंग पथों की सूची से पेड़ संरचना का निर्माण

x1 
| 
|-x2 
| | 
| |-x3 
| | 
| |-x4 
| 
|-x5 

कोई विचार/सुझाव? मेरा मानना ​​है कि तारों की सूची को संसाधित करके पहली बार समस्या पर हमला किया जा सकता है EDIT: चुना गया सही उत्तर एक सुरुचिपूर्ण कार्यान्वयन था, अन्य सुझाव भी अच्छे थे।

+0

शायद तुम मेरी वर्तमान कार्यशील कार्यान्वयन है कि आपके (और मेरा) समस्या का समाधान होगा पढ़ने के लिए दिलचस्पी होगी :) एक नज़र डालें: http://stackoverflow.com/a/10935115/737636 – StErMi

उत्तर

32

एक दर्शनीय पेड़ की भोली कार्यान्वयन के एक कार्यान्वयन का पालन करें: आगंतुक पैटर्न के लिए

class Tree<T> implements Visitable<T> { 

    // NB: LinkedHashSet preserves insertion order 
    private final Set<Tree> children = new LinkedHashSet<Tree>(); 
    private final T data; 

    Tree(T data) { 
     this.data = data; 
    } 

    void accept(Visitor<T> visitor) { 
     visitor.visitData(this, data); 

     for (Tree child : children) { 
      Visitor<T> childVisitor = visitor.visitTree(child); 
      child.accept(childVisitor); 
     } 
    } 

    Tree child(T data) { 
     for (Tree child: children) { 
      if (child.data.equals(data)) { 
       return child; 
      } 
     } 

     return child(new Tree(data)); 
    } 

    Tree child(Tree<T> child) { 
     children.add(child); 
     return child; 
    } 
} 

इंटरफेस:

interface Visitor<T> { 

    Visitor<T> visitTree(Tree<T> tree); 

    void visitData(Tree<T> parent, T data); 
} 

interface Visitable<T> { 

    void accept(Visitor<T> visitor); 
} 

नमूना आगंतुक पैटर्न के लिए कार्यान्वयन:

class PrintIndentedVisitor implements Visitor<String> { 

    private final int indent; 

    PrintIndentedVisitor(int indent) { 
     this.indent = indent; 
    } 

    Visitor<String> visitTree(Tree<String> tree) { 
     return new IndentVisitor(indent + 2); 
    } 

    void visitData(Tree<String> parent, String data) { 
     for (int i = 0; i < indent; i++) { // TODO: naive implementation 
      System.out.print(" "); 
     } 

     System.out.println(data); 
    } 
} 

और अंत में (!!!) एक साधारण परीक्षण का मामला:

Tree<String> forest = new Tree<String>("forest"); 
    Tree<String> current = forest; 

    for (String tree : Arrays.asList("x1/x2/x3", "x1/x2/x4", "x1/x5")) { 
     Tree<String> root = current; 

     for (String data : tree.split("/")) { 
      current = current.child(data); 
     } 

     current = root; 
    } 

    forest.accept(new PrintIndentedVisitor(0)); 

उत्पादन:

 
forest 
    x1 
    x2 
     x3 
     x4 
    x5 
+2

कोड डीएफए के लिए धन्यवाद; यह एक जादू की तरह काम करता है। आगंतुक पैटर्न कार्यान्वयन साफ ​​है। – sushant

+1

मुझसे शादी करो! बहुत उपयोगी उत्तर के लिए धन्यवाद। – ctrlplusb

+0

मैं इसे कैसे कार्यान्वित करूं? कोई जिथब उदाहरण? – TheOnlyAnil

3

मैं एक समय में पेड़ को एक स्ट्रिंग बनाउंगा।

एक खाली पेड़ बनाएं (जिसमें रूट नोड है - मुझे लगता है कि "x7/x8/x9" जैसे पथ हो सकता है)।

पहली स्ट्रिंग लें, रूट नोड में x1 जोड़ें, फिर x2 से x1, फिर x3 से x2।

दूसरी स्ट्रिंग लें, देखें कि x1 और x2 पहले से मौजूद हैं, x4 से x2 जोड़ें।

यह आपके पास हर पथ के लिए करें।

10

बस प्रत्येक पथ को अपने डेलीमीटर द्वारा विभाजित करें और फिर उन्हें एक पेड़ संरचना में एक-एक करके जोड़ें।
यानी 'x1', इस नोड बनाने यदि वह मौजूद इसे करने के लिए जाने के लिए और अगर वहाँ एक बच्चे 'x2' है और इतने पर जाँच करता है मौजूद नहीं है अगर ...

2

एक वस्तु नोड जो एक माता पिता (नोड) और एक होता है बनाएं बच्चों की सूची (नोड)।

पहले "," का उपयोग करके स्ट्रिंग को विभाजित करें। प्रत्येक विभाजित स्ट्रिंग के लिए आप स्ट्रिंग को "/" का उपयोग करके विभाजित करते हैं। रूट सूची में पहले नोड पहचानकर्ता (उदा। X1) के लिए खोजें। यदि आप इसे पा सकते हैं, तो अगले नोड पहचानकर्ता (उदा। X2) को खोजने के लिए नोड का उपयोग करें।

यदि आपको कोई नोड नहीं मिल रहा है, तो अंतिम नोड में नोड जोड़ें जो आप मौजूदा सूचियों में ढूंढ पाए।

सूची संरचना बनाने के बाद, आप सूची को स्क्रीन पर प्रिंट कर सकते हैं। मैं इसे रिकर्सिव बना दूंगा।

नहीं परीक्षण, बस एक एनीमेशन

public void print(List nodes, int deep) { 
    if (nodes == null || nodes.isEmpty()) { 
     return; 
    } 

    StringBuffer buffer = new StringBuffer(); 
    for (int i = 0; i < deep; i++) { 
     buffer.append("---"); 
    } 

    for (Iterator iterator = nodes.iterator(); iterator.hasNext();) { 
     Node node = (Node)iterator.next(); 

     System.out.println(buffer.toString() + " " + node.getIdentifier()); 

     print(node.getChildren(), deep + 1); 
    } 
} 
संबंधित मुद्दे