إنشاء هيكل شجرة من قائمة مسارات السلسلة

StackOverflow https://stackoverflow.com/questions/1005551

  •  05-07-2019
  •  | 
  •  

سؤال

لدي مجموعة من مسارات السلسلة مثل ["x1/x2/x3"، "x1/x2/x4"، "x1/x5"] في القائمة.أحتاج إلى إنشاء هيكل يشبه الشجرة من هذه القائمة والذي يمكن تكراره للحصول على شجرة مطبوعة جميلة.مثله

     x1
    /  \
   x5   x2
       /  \
      x3  x4

أي أفكار / اقتراحات؟أعتقد أنه يمكن مهاجمة المشكلة أولاً عن طريق معالجة قائمة السلاسل EDIT:كانت الإجابة الصحيحة التي تم اختيارها عبارة عن تنفيذ أنيق، وكانت الاقتراحات الأخرى جيدة أيضًا.

هل كانت مفيدة؟

المحلول

واتبع تنفيذا لتنفيذ السذاجة شجرة visitable:

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

نصائح أخرى

ومجرد تقسيم كل مسار من قبل محدد وثم إضافتها إلى هيكل شجرة واحدة تلو الأخرى.
أي إذا 'x1' غير موجود إنشاء هذه العقدة، إذا كان موجود تذهب إليها ومعرفة ما اذا كان هناك 'x2' الأطفال وهلم جرا ...

وكنت جعل شجرة سلسلة واحدة في وقت واحد.

تأكد شجرة فارغة (التي لديها عقدة الجذر - وأفترض أن يكون هناك مسار مثل "X7 / X8 / X9").

وتأخذ السلسلة الأولى، إضافة X1 إلى عقدة الجذر، ثم X2 X1 ل، ثم X3 لX2.

وتأخذ السلسلة الثانية، نرى أن X1 و X2 بالفعل هناك، إضافة إلى X4 X2.

هل هذا كل مسار لديك.

قم بإنشاء عقدة كائن تحتوي على الأصل (العقدة) وقائمة الأطفال (العقدة).

قم أولاً بتقسيم السلسلة باستخدام "،".لكل سلسلة مقسمة تقوم بتقسيم السلسلة باستخدام "/".ابحث عن معرف العقدة الأولى (مثلاً x1) في قائمة الجذر.إذا تمكنت من العثور عليه، فاستخدم العقدة للعثور على معرف العقدة التالي (على سبيل المثال.×2).

إذا لم تتمكن من العثور على عقدة، أضف العقدة إلى العقدة الأخيرة التي تمكنت من العثور عليها في القوائم الموجودة.

بعد إنشاء بنية القائمة، يمكنك طباعة القائمة على الشاشة.سأجعلها متكررة.

لم يتم اختبارها، مجرد الرسوم المتحركة

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);
    }
}

تأكد شجرة الخاص بك عن كل سلسلة في مجموعة. مجرد تقسيم مسار '/'، والتحقق ما إذا كانت العقدة موجودة في شجرة الخاص بك أم لا، إذا كان موجودا ثم الانتقال ... وإلا إنشاء عقدة جديدة وإضافة هذه العقدة في الأطفال من العقدة الأصل.

وحاكي باستخدام العودية.

وفيما يلي نموذج لعقدة الشجرة.

Class Node{
    string name;
    List<Node> childrens;

    Node(string name){
        this.name = name;
        this.childrens = new List<Node>();
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top