2012-03-22 5 views
1

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

Я сделал вспомогательный метод, который сначала проверяет чтобы проверить, является ли элемент 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(); } 
    } 

Я был бы очень признателен какой-либо помощи, или намекают в этом коде. Благодаря

EDIT:

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

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

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

+1

Я не совсем понимаю вопрос, но у меня есть заметки. Если вы мне поняли, код, который вы указали, - это реализация 's' (в следующий раз используйте более четкое соглашение об именах). Теперь представляется возможным, что число из набора не возвращается его итератором, например, когда оно возвращается перед его соответствующими «первыми элементами» в любых парах. Я прав? Это предназначено?Более того, это не будет слишком масштабным, на мой взгляд, вы перебираете много вещей, чтобы получить один кусок, и если я не ошибаюсь, r может стать очень большим. К сожалению, я не могу предложить лучшее решение ... – Vincent

+0

Что касается самого редактирования: открытие нового вопроса обычно лучше, чем редактирование, в котором вы уже приняли ответ. Немногие люди смотрят на уже ответившие на вопросы, если у них нет такой же проблемы, как указано в названии. Что касается содержимого редактирования: что возвращает 'next', если' R' пуст? (Вы можете подумать, что это не так, но eclipse этого не знает.) –

+0

что касается правильности: напишите тест или основной метод, добавив несколько пар и посмотрим, подходит ли он для начала (было бы здорово, если бы ваш тип элемента не ограничивались целым числом, поэтому вы можете протестировать его с элементами, которые не имеют естественного порядка, известного java). Для нетривиального теста с целыми парами попробуйте, например: 1-0, 2-0, 4-3, 5-1, 5-4, 3-2 (чтобы сделать его немного более злым, можно добавить 5 -0 перед другими). Итератор элемента должен возвращать 5-4-3-2-0 в этом порядке и 1 в любом месте. Да, это очень интересная проблема. :-) –

ответ

1

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

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

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

, а затем, перед его возвращением в вашей цикл, добавить его там:

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 и список отношений?

+0

+1 сохранить структуру заказанный во время строительства – Vincent

+0

Наличие другой структуры данных для хранения возвращенных элементов, по-видимому, является хорошей идеей, я попробую и опубликую результаты, когда я это сделаю. Thanks arne.b –

Смежные вопросы