1

Тема: Ітератор шляхів

Є рандом стрічка виду :"[string1].string2.some.[.].[new].[].lastthing.main.[string[substring].[substring2]].[this.is.a.one.substring].[gergregertgerggrgre.gt.[ff]].somemoretext.[[this].is.[also].[one.[substring]]]."

Шляхом називається стрічка, яка використовує розділювач '.' для поділу себе на елементи.
Елементом є стрічка між розділювачами.
Початок і кінець шляху також вважаються розділювачами. '.' є розділювачем, якщо він не обмежений квадратними дужками.
Елементи можуть бути взяті у квадратні дужки для того, щоби мати можливість містити в собі символи '.', і інші символи '[', ']'. Елемент вважається взятим в квадратні дужки, якщо кількість відкритих квадратних дужок рівна кількості закритих. Вважати, що ітератор повинен працювати тільки з правильними вхідними стрічками.
Створити ітератор шляху PathIterator. Його метод next() повинен повертати елементи стрічки в такому порядку, в якому вони зустрічаються в шляху. Елементи взяті в квадратні дужки повертаються без квадратних дужок. Метод hasNext() повинен повертати true, якщо ще не всі елементи шляху повернено і false в іншому випадку. При виклику метода remove(), повиннен викидатися java.lang.UnsupportedOperationException.

Потрібен хоча б натяк як має виглядати метод next()...

2

Re: Ітератор шляхів

Класичний скінчений автомат. Якщо маємо що завгодно, крім [ - ідемо по одному символу і додаємо в результат, доки не зустрінемо ., коли зустріли - пропускаємо і повертаємо результат. Якщо [ - лічимо символи [] ([ додаємо 1, ] - віднімаємо 1), доки не вийде 0, і додаємо всі символи, крім першої і останньої дужки, до результату.

Подякували: ldegyl, leofun012

3 Востаннє редагувалося leofun01 (02.04.2016 18:02:44)

Re: Ітератор шляхів

PathIterator:

// PathIterator.java

package javaiterator;
import java.util.Iterator;

public class PathIterator implements Iterator<String> {

    private final String string;
    private Integer index;

    public PathIterator(String s) { string = s; index = -1; }

    @Override
    public boolean hasNext() { return index < string.length(); }

    @Override
    public String next() {
        Integer brakets = 0, start = index, length = string.length();
        Character ch;
        while(++index < length &&
            ((ch = string.charAt(index)) != '.' || brakets > 0))
                if(ch == '[') ++brakets;
                else if(ch == ']') --brakets;
        return string.substring(++start, index);
    }
}

Main для перевірки

// Main.java

package javaiterator;
import java.io.*;

public class Main {
    public static void main(String[] args) {
        String s = "[string1].string2.some.[.].[new].[].lastthing.main." +
            "[string[substring].[substring2]].[this.is.a.one.substring]." +
            "[gergregertgerggrgre.gt.[ff]].somemoretext." +
            "[[this].is.[also].[one.[substring]]].";
        System.out.println(s);
        System.out.println();
        PathIterator iterator = new PathIterator(s);
        while(iterator.hasNext())
            System.out.println(iterator.next());
        System.out.println();
        System.out.println("Press enter to exit.");
        BufferedReader in = new BufferedReader(
            new InputStreamReader(System.in));
        try { in.readLine(); }
        catch (IOException ex) { ex.printStackTrace(System.out); }
    }
}

Здається працює. Перед використанням краще потестувати.

Подякували: ldegyl, koala2

4 Востаннє редагувалося leofun01 (02.04.2016 19:30:19)

Re: Ітератор шляхів

ldegyl написав:

Елементи взяті в квадратні дужки повертаються без квадратних дужок.

Вибачте, не помітив цієї умови.
Ось так має бути добре:

// PathIterator.java

package javaiterator;

import java.util.Iterator;

public class PathIterator implements Iterator<String> {

    private final String string;
    private int index;

    public PathIterator(String s) { string = s; index = -1; }

    @Override
    public boolean hasNext() { return index < string.length(); }

    @Override
    public String next() {
        int start = index, length = string.length();
        char ch;
        while(++index < length && (ch = string.charAt(index)) != '.')
            if(ch == '[') index = getIndexOfCloseBraket(string, index);
        return trimBrakets(string.substring(++start, index));
    }

    public static String trimBrakets(String s)
    {
        int start = 0, length = s.length();
        if(--length < 0) return s;
        while(s.charAt(start) == '[' &&
            getIndexOfCloseBraket(s, start) == length)
        {
            ++start;
            --length;
        }
        return s.substring(start, ++length);
    }

    public static int getIndexOfCloseBraket(String s, int open) {
        int brakets = 1, length = s.length();
        char ch;
        while(++open < length && brakets > 0)
            if((ch = s.charAt(open)) == '[') ++brakets;
            else if(ch == ']') --brakets;
        return --open;
    }
}
Подякували: koala1

5

Re: Ітератор шляхів

Я Вам дуже вдячний за допомогу але і остання спроба теж не відповідає умовам завдання)

6 Востаннє редагувалося leofun01 (02.04.2016 22:32:09)

Re: Ітератор шляхів

ldegyl написав:

... остання спроба теж не відповідає умовам завдання)

Я ще кілька разів прочитав завдання і не знайшов власних помилок.
Можливо я щось не правильно зрозумів, або є ще якісь додаткові умови ?
Давайте розглянемо наведену стрічку:

ldegyl написав:

[string1].string2.some.[.].[new].[].lastthing.main.[string[substring].[substring2]].[this.is.a.one.substring].[gergregertgerggrgre.gt.[ff]].somemoretext.[[this].is.[also].[one.[substring]]].

Тут наведено те, що повернув мій ітератор
string1
string2
some
.
new

lastthing
main
string[substring].[substring2]
this.is.a.one.substring
gergregertgerggrgre.gt.[ff]
somemoretext
[this].is.[also].[one.[substring]]

На вашу думку, що саме має повертати ітератор при кожному виклику next() ?
Наведіть приклад від початку і до кінця.

7

Re: Ітератор шляхів

"Елемент вважається взятим в квадратні дужки, якщо кількість відкритих квадратних дужок рівна кількості закритих."  "Елементи взяті в квадратні дужки повертаються без квадратних дужок". Мені здається це умова для всіх дужок навіть для тих, які були в дужках, тобто всі дужки мають бути відкинуті.

8 Востаннє редагувалося leofun01 (02.04.2016 23:07:42)

Re: Ітератор шляхів

Не бачу проблем.
В main заміняєте

        while(iterator.hasNext())
            System.out.println(iterator.next());

на

        while(iterator.hasNext())
            System.out.println(iterator.next()
                .replaceAll("\\[", "").replaceAll("\\]", ""));

і дужок [] взагалі не буде.

P.S. Але в такому випадку порушується структура шляху і поняття шляху втрачає сенс.

9

Re: Ітератор шляхів

Я ще раз Вам дякую за допомогу, мабуть моя проблема в тому що це не мій рівень знань)

10

Re: Ітератор шляхів

Як що комусь буде потрибно це правільне рішення

 private static String filter(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }
        StringBuilder out = new StringBuilder(input.length());
        int openedBraces = 0;
        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            switch (c) {
                case '[':
                    openedBraces++;
                    break;
                case ']':
                    if (openedBraces > 0) {
                        openedBraces--;
                    } else {
                        throw new IllegalArgumentException("Unexpected closing brace at " + i);
                    }
                    break;
                case '.':
                    if (openedBraces > 0) {
                        out.append(c);
                    }
                    else {
                        out.append(" ");
                    }
                    break;
                default:
                    out.append(c);
                    break;
            }
        }
        return out.toString();
    }
Подякували: koala1

11

Re: Ітератор шляхів

Я радий, що це рішення вас влаштовує, але воно не є правильним рішенням цієї задачі. Зокрема тому, що тут немає ані ітератора, ані next, ані hasNext, ані UnsupportedOperationException.

Подякували: leofun011

12

Re: Ітератор шляхів

Може й так, але цей варіант єдиний з тих що я можу написати. І він робить те що потрібно. Знаєте кращчий я буду вдячний за приклад.