2012-12-10 10 views
8

Biorąc pod uwagę obiekt Set, chcę przejść przez wszystkie (nieuporządkowane) pary tego.Jak efektywnie uzyskać wszystkie pary zestawów?

Przykład: Ustaw = {1, 2, 3}, Pary: (1, 2), (1, 3), (2, 3).

Gdy mamy do czynienia z Vector<Integer>, można to osiągnąć przy pomocy indeksu każdego elementu:

for (int i = 0; i < vector.size(); i++) 
    for (int j = i + 1; j < vector.size(); j++) 
    // Do something with vector.get(i) and vector.get(j) 

Ale elementy w Set<Integer> mają żadnych indeksów.

Najlepsze rozwiązanie, jakie dotychczas znalazłem, to przekonwertować Set na Vector i skorzystać z powyższego rozwiązania.

Czy istnieje bardziej wydajne/bezpośrednie rozwiązanie?

+0

Potrzebujesz tylko wektora/macierzy w zagnieżdżonej pętli. Ale poza tym, myślę, że to najlepsze rozwiązanie. – Jochen

+4

Wektor? Dlaczego nie ma listy? –

+0

@Jochen Myślę, że lista jest preferowanym rozwiązaniem. –

Odpowiedz

9
List<Integer> list = new ArrayList<Integer>(mySet); 
for (int i = 0; i < list .size(); i++) 
    for (int j = i + 1; j < list .size(); j++) 
     // Do something with vector.get(i) and vector.get(j) 
+2

Op powiedział on musi zrobić to samo z zestawem, on już wie, jak zrobić z listą. # – PermGenError

+0

Dziękuję. Ale jak już powiedziałem, to rozwiązanie działa. Czy istnieje inny bez konwersji (i być może bardziej wydajny)? –

+0

Jak można się spodziewać, że będzie bardziej wydajny, będzie to "O (n)", tak samo jak przykładowy kod. –

1

Pod względem złożoności dla tego algorytmu = n (n -1)/2, więc O (n^2) jest najlepszy można dostać (sekwencyjna).

Chociaż zestaw jest naprawdę duży, zestaw pasuje tylko do pamięci RAM. Możesz zoptymalizować algorytm, obliczając parę w sposób podobny do tego, co robi się w mnożeniu macierzy za pomocą bloków kafli. W ten sposób można zmniejszyć% braków pamięci podręcznej, a tym samym zwiększyć ogólną wydajność.

Oprócz tego można wprowadzić równoległość i podzielić pracę między wątkami/procesami, ponieważ algorytm wydaje się zawstydzająco równoległy.

+0

Czy możesz rozwinąć "obliczanie pary w sposób podobny do tego, co się robi w mnożeniu macierzy za pomocą bloków płytek" –

+0

Trudno wyjaśnić przez komentarz, ale możesz sprawdzić tę technikę wykorzystania w gnu: http: // www. umiacs.umd.edu/~ramani/cmsc828e_gpusci/Lecture5.pdf Ale jest bardzo podobny do tego, którego używa się również w procesorze. i https://en.wikipedia.org/wiki/Loop_tiling – dreamcrash