Menggunakan C ++, dan mudah-mudahan perpustakaan standar, saya ingin mengurutkan urutan sampel dalam urutan menaik, tetapi saya juga ingin mengingat indeks asli dari sampel baru.
Sebagai contoh, saya memiliki satu set, atau vektor, atau matriks sampel A : [5, 2, 1, 4, 3]
. Saya ingin mengurutkan ini menjadi B : [1,2,3,4,5]
, tetapi saya juga ingin mengingat indeks asli dari nilai-nilai, sehingga saya bisa mendapatkan set lain yang akan menjadi:
C : [2, 1, 4, 3, 0 ]
- yang sesuai dengan indeks setiap elemen dalam 'B', dalam yang asli ' SEBUAH'.
Misalnya, di Matlab Anda dapat melakukan:
[a,b]=sort([5, 8, 7])
a = 5 7 8
b = 1 3 2
Adakah yang bisa melihat cara yang baik untuk melakukan ini?
for (size_t i = 0; i != idx.size(); ++i) idx[i] = i;
saya lebih suka standarstd::iota( idx.begin(), idx.end(), 0 );
#include <numeric>
untuk iota ()iota
adalah algoritma yang paling tidak jelas namanya di seluruh pustaka standar C ++.Anda bisa mengurutkan std :: pair bukan hanya ints - int pertama adalah data asli, int kedua adalah indeks asli. Kemudian sediakan komparator yang hanya memilah pada int pertama. Contoh:
Urutkan instance masalah baru menggunakan pembanding seperti:
Hasil std :: sort pada v_prime, menggunakan komparator itu, seharusnya:
Anda dapat mengupas indeks dengan berjalan vektor, meraih .second dari setiap std :: pair.
sumber
Misalkan vektor yang diberikan adalah
Buat vektor baru
Sortir V dan sambil menyortir alih-alih membandingkan elemen V, bandingkan elemen A yang sesuai
sumber
std::iota()
inisialisasi yang lebih eleganmap
Saya menulis versi generik dari semacam indeks.
Penggunaannya sama dengan std :: sort kecuali untuk wadah indeks untuk menerima indeks yang diurutkan. pengujian:
Anda harus mendapatkan 2 1 0 3. untuk kompiler tanpa dukungan c ++ 0x, ganti ekspresi lamba sebagai templat kelas:
dan tulis ulang std :: sortir sebagai
sumber
Sekarang
a
berisi nilai kami dan indeks masing-masing dalam diurutkan.a[i].first = value
padai
'th.a[i].second = idx
dalam array awal.sumber
Saya menemukan pertanyaan ini, dan menemukan mengurutkan iterator secara langsung akan menjadi cara untuk mengurutkan nilai-nilai dan melacak indeks; Tidak perlu mendefinisikan wadah tambahan
pair
s (nilai, indeks) yang bermanfaat ketika nilai adalah objek besar; Iterator menyediakan akses ke nilai dan indeks:adapun contoh penggunaan:
sekarang, misalnya, elemen terkecil ke-5 dalam vektor yang diurutkan akan memiliki nilai
**idx[ 5 ]
dan indeksnya dalam vektor asli adalahdistance( A.begin( ), *idx[ 5 ] )
atau sederhana*idx[ 5 ] - A.begin( )
.sumber
Ada cara lain untuk menyelesaikan ini, menggunakan peta:
Ini akan menghilangkan elemen non-unik. Jika itu tidak dapat diterima, gunakan multimap:
Untuk menampilkan indeks, lakukan iterasi pada peta atau multimap:
sumber
Solusi indah oleh @Lukasz Wiklendt! Meskipun dalam kasus saya, saya membutuhkan sesuatu yang lebih umum, jadi saya memodifikasinya sedikit:
Contoh: Temukan indeks yang mengurutkan vektor string berdasarkan panjangnya, kecuali untuk elemen pertama yang merupakan dummy.
cetakan:
sumber
Pertimbangkan untuk menggunakan
std::multimap
seperti yang disarankan oleh @Ulrich Eckhardt. Hanya saja kodenya bisa dibuat lebih sederhana.Diberikan
Untuk mengurutkan waktu penyisipan rata-rata
Untuk mengambil nilai dan indeks asli
Alasan untuk memilih a
std::multimap
ke astd::map
adalah untuk memungkinkan nilai yang sama dalam vektor asli. Perlu diketahui juga, tidak seperti untukstd::map
,operator[]
tidak ditentukan untukstd::multimap
.sumber
Membuat
std::pair
fungsi dalam lalu sortir pasangan:versi generik:
ideone
sumber
Apakah item dalam vektor unik? Jika demikian, salin vektor, urutkan salah satu salinan dengan STL Sort maka Anda dapat menemukan indeks yang dimiliki setiap item dalam vektor asli.
Jika vektor seharusnya menangani item duplikat, saya pikir Anda lebih baik menerapkan rutinitas semacam Anda sendiri.
sumber
Nah, solusi saya menggunakan teknik residu. Kita dapat menempatkan nilai-nilai di bawah pengurutan di 2 byte atas dan indeks elemen - dalam 2 byte lebih rendah:
Kemudian urutkan array
myints
seperti biasa:Setelah itu Anda dapat mengakses indeks elemen melalui residuum. Kode berikut mencetak indeks nilai yang diurutkan dalam urutan naik:
Tentu saja, teknik ini hanya berfungsi untuk nilai-nilai yang relatif kecil dalam array asli
myints
(yaitu yang dapat masuk ke dalam 2 byte atasint
). Tetapi memiliki manfaat tambahan untuk membedakan nilai identikmyints
: indeks mereka akan dicetak dalam urutan yang benar.sumber
Jika memungkinkan, Anda dapat membuat susunan posisi menggunakan fungsi find, dan kemudian mengurutkan susunan.
Atau mungkin Anda dapat menggunakan peta di mana kunci akan menjadi elemen, dan nilai-nilai daftar posisinya di array yang akan datang (A, B dan C)
Itu tergantung pada penggunaan nanti dari array itu.
sumber
Untuk jenis pertanyaan ini Simpan data array orignal ke dalam data baru dan kemudian pencarian biner elemen pertama dari array yang diurutkan ke dalam array yang digandakan dan bahwa indice harus disimpan ke dalam vektor atau array.
Di sini binarysearch adalah fungsi yang mengambil array, ukuran array, mencari item dan akan mengembalikan posisi item yang dicari
sumber
Ada banyak cara. Solusi yang agak sederhana adalah dengan menggunakan vektor 2D.
Berikut hasilnya:
sumber