отображение списка строк в иерархическую структуру объектов

Это не домашнее задание. Этот вопрос был задан одному из моих друзей на собеседовании.

У меня есть списокстрок, считанных из файла в качестве входных данных. Каждая строка имеет идентификатор, такой как (A,B,NN,C,DD) в начале строки.В зависимости от идентификатора мне нужно сопоставить список записей с одним объектом A, который содержит иерархическую структуру объектов.

enter image description here

Описание Иерархии: Каждый Aможет иметь ноль или более типов B. Каждый идентификатор Bможет иметь ноль или более NNи Cв качестве дочерних. Точно так же каждый сегмент Cможет иметь ноль или более дочерних NNи DD. Каждый DDможет иметь ноль или более NNв качестве дочерних.

Сопоставление классов и их иерархия:

Все классы будут иметь значениедля хранения значения Stringиз текущей строки.

**A - will have list of B**

    class A {
        List<B> bList;
        String value;

        public A(String value) {
            this.value = value;
        }

        public void addB(B b) {
            if (bList == null) {
                bList = new ArrayList<B>();
            }
            bList.add(b);
        }
    }


**B - will have list of NN and list of C**

    class B {
            List<C> cList;
            List<NN> nnList;
            String value;
                public B(String value) {
                this.value = value;
            }
                public void addNN(NN nn) {
                if (nnList == null) {
                    nnList = new ArrayList<NN>();
                }
                nnList.add(nn);
            }
                public void addC(C c) {
                if (cList == null) {
                    cList = new ArrayList<C>();
                }
                cList.add(c);
            }
        }

**C - will have list of DDs and NNs**

    class C {
            List<DD> ddList;
            List<NN> nnList;
            String value;
            public C(String value) {
                this.value = value;
            }
            public void addDD(DD dd) {
                if (ddList == null) {
                    ddList = new ArrayList<DD>();
                }
                ddList.add(dd);
            }
            public void addNN(NN nn) {
                if (nnList == null) {
                    nnList = new ArrayList<NN>();
                }
                nnList.add(nn);
            }
        }

**DD - will have list of NNs**

    class DD {
            String value;
            List<NN> nnList;
            public DD(String value) {
                this.value = value;
            }
            public void addNN(NN nn) {
                if (nnList == null) {
                    nnList = new ArrayList<NN>();
                }
                nnList.add(nn);
            }
        }

**NN- will hold the line only**

    class NN {
        String value;

        public NN(String value) {
            this.value = value;
        }
    }

Что я сделал на данный момент:

Метод public A parse(List lines)считывает входной список и возвращает объект A. Поскольку может быть несколько B, я создал отдельный метод 'parseBдля анализа каждого вхождения.

В методе parseBперебирает i = startIndex + 1 до i < lines.size()и проверяет начало строк. Вхождение "NN" добавляется к текущему объекту B. Если при запуске обнаруживается "C", вызывается другой метод parseC. Цикл разорвется, когда мы обнаружим «B» или «A» в начале.

Аналогичная логика используется в parseC_DD.

public class GTTest {    
    public A parse(List<String> lines) {
        A a;
        for (int i = 0; i < lines.size(); i++) {
            String curLine = lines.get(i);
            if (curLine.startsWith("A")) { 
                a = new A(curLine);
                continue;
            }
            if (curLine.startsWith("B")) {
                i = parseB(lines, i); // returns index i to skip all the lines that are read inside parseB(...)
                continue;
            }
        }
        return a; // return mapped object
    }

    private int parseB(List<String> lines, int startIndex) {
        int i;
        B b = new B(lines.get(startIndex));
        for (i = startIndex + 1; i < lines.size(); i++) {
            String curLine = lines.get(i);
            if (curLine.startsWith("NN")) {
                b.addNN(new NN(curLine));
                continue;
            }
            if (curLine.startsWith("C")) {
                i = parseC(b, lines, i);
                continue;
            }
            a.addB(b);
            if (curLine.startsWith("B") || curLine.startsWith("A")) { //ending condition
                System.out.println("B A "+curLine);
                --i;
                break;
            }
        }
        return i; // return nextIndex to read
    }

    private int parseC(B b, List<String> lines, int startIndex) {

        int i;
        C c = new C(lines.get(startIndex));

        for (i = startIndex + 1; i < lines.size(); i++) {
            String curLine = lines.get(i);
            if (curLine.startsWith("NN")) {
                c.addNN(new NN(curLine));
                continue;
            }           

            if (curLine.startsWith("DD")) {
                i = parseC_DD(c, lines, i);
                continue;
            }

            b.addC(c);
            if (curLine.startsWith("C") || curLine.startsWith("A") || curLine.startsWith("B")) {
                System.out.println("C A B "+curLine);
                --i;
                break;
            }
        }
        return i;//return next index

    }

    private int parseC_DD(C c, List<String> lines, int startIndex) {
        int i;
        DD d = new DD(lines.get(startIndex));
        c.addDD(d);
        for (i = startIndex; i < lines.size(); i++) {
            String curLine = lines.get(i);
            if (curLine.startsWith("NN")) {
                d.addNN(new NN(curLine));
                continue;
            }
            if (curLine.startsWith("DD")) {
                d=new DD(curLine);
                continue;
            }       
            c.addDD(d);
            if (curLine.startsWith("NN") || curLine.startsWith("C") || curLine.startsWith("A") || curLine.startsWith("B")) {
                System.out.println("NN C A B "+curLine);
                --i;
                break;
            }

        }
        return i;//return next index

    }
public static void main(String[] args) {
        GTTest gt = new GTTest();
        List<String> list = new ArrayList<String>();
        list.add("A1");
        list.add("B1");
        list.add("NN1");
        list.add("NN2");
        list.add("C1");
        list.add("NNXX");
        list.add("DD1");
        list.add("DD2");
        list.add("NN3");
        list.add("NN4");
        list.add("DD3");
        list.add("NN5");
        list.add("B2");
        list.add("NN6");
        list.add("C2");
        list.add("DD4");
        list.add("DD5");
        list.add("NN7");
        list.add("NN8");
        list.add("DD6");
        list.add("NN7");
        list.add("C3");
        list.add("DD7");
        list.add("DD8");
        A a = gt.parse(list);
            //show values of a 

    }
}

Моя логика работает неправильно. Есть ли другой подход, который вы можете понять? Есть ли у вас предложения/улучшения моего пути?

10
задан gtiwari333 5 April 2012 в 04:59
поделиться