Korzystając z C ++ i, mam nadzieję, ze standardowej biblioteki, chcę posortować sekwencję próbek w kolejności rosnącej, ale chcę również zapamiętać oryginalne indeksy nowych próbek.
Na przykład mam zestaw lub wektor lub macierz próbek A : [5, 2, 1, 4, 3]
. Chcę je posortować B : [1,2,3,4,5]
, ale chcę też pamiętać oryginalne indeksy wartości, aby uzyskać inny zestaw, który byłby:
C : [2, 1, 4, 3, 0 ]
- który odpowiada indeksowi każdego elementu w „B”, w oryginalnym „ ZA'.
Na przykład w Matlab możesz wykonać:
[a,b]=sort([5, 8, 7])
a = 5 7 8
b = 1 3 2
Czy ktoś może zobaczyć dobry sposób na zrobienie tego?
for (size_t i = 0; i != idx.size(); ++i) idx[i] = i;
wolę standardstd::iota( idx.begin(), idx.end(), 0 );
#include <numeric>
for iota ()iota
jest najmniej oczywistym nazwanym algorytmem w całej standardowej bibliotece C ++.Możesz sortować std :: pair zamiast tylko ints - pierwsza int to oryginalne dane, druga int to oryginalny indeks. Następnie podaj komparator, który sortuje tylko na pierwszej int. Przykład:
Posortuj nowe wystąpienie problemu za pomocą komparatora, takiego jak:
Wynikiem użycia std :: sort na v_prime przy użyciu tego komparatora powinno być:
Możesz obrać indeksy, chodząc po wektorze, chwytając .second z każdej std :: pair.
źródło
Załóżmy, że dany wektor to
Utwórz nowy wektor
Posortuj V i podczas sortowania zamiast porównywania elementów V, porównaj odpowiednie elementy A
źródło
std::iota()
do bardziej eleganckiej inicjalizacjimap
Napisałem ogólną wersję sortowania indeksu.
Użycie jest takie samo, jak w przypadku std :: sort, z wyjątkiem kontenera indeksów do odbierania posortowanych indeksów. testowanie:
powinieneś dostać 2 1 0 3. dla kompilatorów bez obsługi c ++ 0x, zamień wyrażenie lamba jako szablon klasy:
i przepisz std :: sort as
źródło
Teraz
a
zawiera zarówno nasze wartości, jak i ich odpowiednie wskaźniki w posortowanym.a[i].first = value
o godzi
.a[i].second = idx
w początkowej tablicy.źródło
Natknąłem się na to pytanie i doszedłem do wniosku, że bezpośrednie sortowanie iteratorów byłoby sposobem na uporządkowanie wartości i śledzenie indeksów; Nie ma potrzeby definiowania dodatkowego kontenera
pair
s (wartości, indeksu), który jest pomocny, gdy wartości są dużymi obiektami; Iteratory zapewniają dostęp zarówno do wartości, jak i do indeksu:jak w przykładzie użycia:
teraz na przykład piąty najmniejszy element w posortowanym wektorze miałby wartość,
**idx[ 5 ]
a jego indeks w oryginalnym wektorze byłbydistance( A.begin( ), *idx[ 5 ] )
lub po prostu*idx[ 5 ] - A.begin( )
.źródło
Istnieje inny sposób rozwiązania tego problemu za pomocą mapy:
Spowoduje to jednak usunięcie nie unikalnych elementów. Jeśli nie jest to możliwe, użyj mapy wielopunktowej:
Aby wygenerować wskaźniki, iteruj po mapie lub multimapie:
źródło
Piękne rozwiązanie autorstwa @L Łukasz Wiklendt! Chociaż w moim przypadku potrzebowałem czegoś bardziej ogólnego, więc nieco go zmodyfikowałem:
Przykład: Znajdź indeksy sortujące wektor ciągów według długości, z wyjątkiem pierwszego elementu, który jest atrapą.
drukuje:
źródło
Rozważ użycie
std::multimap
sugerowane przez @Ulricha Eckhardta. Wystarczy, że kod może być jeszcze prostszy.Dany
Aby posortować według średniego czasu wstawienia
Aby pobrać wartości i oryginalne indeksy
Powodem wolą
std::multimap
Dostd::map
to, aby umożliwić równe wartości w oryginalnych wektorów. Należy również pamiętać, że w przeciwieństwie dostd::map
,operator[]
nie jest zdefiniowane dlastd::multimap
.źródło
Utwórz funkcję
std::pair
in, a następnie posortuj parę:wersja ogólna:
ideone
źródło
Czy elementy w wektorze są unikalne? Jeśli tak, skopiuj wektor, posortuj jedną z kopii za pomocą STL Sort, a następnie możesz znaleźć indeks, który każdy element miał w oryginalnym wektorze.
Jeśli wektor ma obsługiwać zduplikowane elementy, myślę, że lepiej wdrożyć własną procedurę sortowania.
źródło
Moje rozwiązanie wykorzystuje technikę pozostałości. Możemy umieszczać wartości w sortowaniu w górnych 2 bajtach, a indeksy elementów - w dolnych 2 bajtach:
Następnie posortuj tablicę
myints
jak zwykle:Następnie możesz uzyskać dostęp do indeksów elementów za pośrednictwem residuum. Poniższy kod drukuje indeksy wartości posortowane w porządku rosnącym:
Oczywiście ta technika działa tylko dla względnie małych wartości w oryginalnej tablicy
myints
(tj. Tych, które mogą zmieścić się w 2 górnych bajtachint
). Ma jednak dodatkową zaletę polegającą na odróżnianiu identycznych wartościmyints
: ich indeksy będą drukowane we właściwej kolejności.źródło
Jeśli to możliwe, możesz zbudować tablicę pozycji za pomocą funkcji find, a następnie posortować tablicę.
A może możesz użyć mapy, w której kluczem byłby element, a wartościuje listę jego pozycji w nadchodzących tablicach (A, B i C)
To zależy od późniejszych zastosowań tych tablic.
źródło
W przypadku tego typu pytań należy zapisać dane z tablicy pierwotnej w nowych danych, a następnie przeszukać binarnie pierwszy element posortowanej tablicy w zduplikowanej tablicy, a ten indeks należy zapisać w wektorze lub tablicy.
Tutaj binarysearch jest funkcją, która pobiera tablicę, rozmiar tablicy, szukany element i zwraca pozycję szukanego elementu
źródło
Jest wiele sposobów. Dość prostym rozwiązaniem jest użycie wektora 2D.
Oto wynik:
źródło