Порядок итерации Poset / пользовательская реализация итератора для частично упорядоченного набора - PullRequest
1 голос
/ 23 марта 2012

Я создаю частично упорядоченный набор как абстрактный тип данных в Java, и мне нужно сделать версию набора чисел итератором и итератор для отношений.Теперь для элементов я использовал HashSet для целых чисел, а для отношений я использовал ArrayList пар (пары - это класс, который я создал, который принимает 2 дюйма в качестве параметра, который в основном похож на (x, y)).Мне нужно сделать 2 итератора, один для s и один для r, но они должны следовать определенному порядку, 1. если (x, y) принадлежат R, то итератор s должен вернуть x, прежде чем он вернет y2. если (x, y) и (y, z) принадлежат R, то итератор r должен вернуть (x, y), прежде чем он вернет (y, z)

Я создал вспомогательный методэта проверка в первую очередь, чтобы проверить, является ли элемент n в наборе первым элементом в паре, затем он возвращает его, но я не могу проверить, является ли он вторым элементом, как я могу проверить первый элемент, если он возвращается илине так?

Вот мой код:

private class IntGenerator implements Iterator {
        private Iterator<Integer> i;


        public IntGenerator () {
            i = S.iterator();
        }

        public boolean hasNext() {
            return i.hasNext();
        }

        public Object next() {
            int n = i.next();

            for (Pair p : R) {
                if (isInFirstElmPair(p,  n)) return n;
                else (isInSecondElmPair(p, n)) {
                                    // should check for the first element
                                    // if it was returned or not
                }
            }
        }

        public void remove() { throw new UnsupportedOperationException(); }
    }

Я был бы очень признателен за любую помощь или подсказку в этом коде.Спасибо

РЕДАКТИРОВАТЬ:

Хорошо, я написал код для него после добавления нового набора, который будет содержать возвращенные элементы, и это то, что я написал:

Set<Integer> returnedNumbers = new HashSet<Integer> ();
public Object next() {
            int n = i.next();

            for (Pair p : R) {
                if (isInSecondElmPair(p, n)) {
                    if (returnedNumbers.contains(p.getFirstElm())) {
                        returnedNumbers.add(n);
                        return n;
                    }else{
                        returnedNumbers.add(p.getFirstElm());
                        return p.getFirstElm();
                    }
                }else{
                    returnedNumbers.add(n);
                    return n;
                }
            }
        }

Этот код правильный?Кроме того, затмение, кажется, дает мне ошибку, сообщая мне, что мне нужно вернуть значение вне цикла, но я уже возвращался внутрь для каждого случая, зачем ему больше?Ценю помощь

1 Ответ

1 голос
/ 23 марта 2012

Что ж, чтобы проверить, было ли ранее возвращено значение, вам, конечно, нужно отслеживать все значения, которые были возвращены ранее.

Так что в вашем итераторе вы можете определить

Set<Integer> previouslyReturned = new HashSet<Integer>();

и затем, прежде чем вернуть его в свой цикл for, добавьте его туда:

if (isInFirstElmPair(p,  n)) {
    previouslyReturned.add(n);
    return n;
}
else (isInSecondElmPair(p, n)) {
    if (previouslyReturned.contains(n) {
        // do one thing
    } else {
        // do another thing
    }
}

Таким образом, однако, вы строите набор s в порядке, в котором он должен быть возвращен внутри итератора .Имеет смысл создать его один раз (рассмотрим LinkedHashSet), сохранить его где-нибудь еще и повторить его.

В общем, я не уверен, что этот подход приведет к тому, что вы хотите.Знаете ли вы что-нибудь о порядке элементов в S и R?Если порядок итераций произвольный (т. Е. Поскольку отношения были добавлены в непредсказуемом порядке), то итератор сначала вернет первую половину первой пары отношений, даже если этот элемент находится во второй половине другой пары.У вас есть для использования элемента HashSet и списка отношений?

...