Haruskah saya gunakan
std::sort(numbers.begin(), numbers.end(), std::greater<int>());
atau
std::sort(numbers.rbegin(), numbers.rend()); // note: reverse iterators
untuk mengurutkan vektor dalam urutan menurun? Apakah ada manfaat atau kelemahan dengan satu pendekatan atau yang lain?
reverse_iterator
itu.std::sort(b, e);
menempatkan minimum dib
(dalam kasus kamirbegin
, jadi elemen terakhir ) dan maksimum die
(dalam kasus kamirend
, jadi elemen pertama ).Jawaban:
Sebenarnya, yang pertama adalah ide yang buruk. Gunakan yang kedua , atau ini:
Dengan cara itu kode Anda tidak akan diam-diam rusak ketika seseorang memutuskan
numbers
harus menahanlong
ataulong long
bukannyaint
.sumber
greater
selain itu?rbegin
danrend
dibuat untuk tujuan tertentu.std::greater<typename decltype(numbers)::value_type>()
atau apa?std::greater<>()
sejak C ++ 14.Gunakan yang pertama:
Ini eksplisit apa yang terjadi - lebih sedikit kesempatan untuk salah membaca
rbegin
sebagaibegin
, bahkan dengan komentar. Ini jelas dan mudah dibaca yang persis apa yang Anda inginkan.Juga, yang kedua mungkin kurang efisien daripada yang pertama mengingat sifat iterator terbalik, meskipun Anda harus membuat profil untuk memastikannya.
sumber
Dengan c ++ 14 Anda dapat melakukan ini:
sumber
Bagaimana dengan ini?
sumber
=
dan+
hanya kenyamanan makna∈
dan∪
. Dalam hal ini,O(n*log(n)) + O(n)
adalah notasi yang nyamanO(n*log(n)) ∪ O(n)
yang sama denganO(n*log(n))
. Kata "perhitungan" adalah saran yang bagus dan Anda benar tentang nadanya.Alih-alih functor seperti yang diusulkan Mehrdad, Anda bisa menggunakan fungsi Lambda.
sumber
Menurut mesin saya, mengurutkan
long long
vektor [1..3000000] menggunakan metode pertama membutuhkan waktu sekitar 4 detik, sedangkan menggunakan yang kedua membutuhkan waktu sekitar dua kali lipat. Itu mengatakan sesuatu, tentu saja, tetapi saya juga tidak mengerti mengapa. Hanya berpikir ini akan sangat membantu.Hal yang sama dilaporkan di sini .
Seperti yang dikatakan oleh Xeo, dengan
-O3
mereka menggunakan waktu yang hampir bersamaan untuk menyelesaikannya.sumber
reverse_iterator
operasi tidak inline, dan mengingat bahwa mereka hanya pembungkus di sekitar iterator yang sebenarnya, tidak heran mereka mengambil dua kali lipat waktu tanpa inline.base()
anggota misalnya mengembalikan iterator yang dibungkus.std::vector<>::reverse_iterator
diterapkan dalam halstd::reverse_iterator<>
. Aneh; hari ini saya belajar. :-PAnda dapat menggunakan pendekatan pertama karena mendapatkan lebih banyak efisiensi daripada yang kedua.
Kompleksitas waktu pendekatan pertama kurang dari yang kedua.
sumber
sumber
TL; DR
Gunakan apa saja. Mereka hampir sama.
Jawaban yang membosankan
Seperti biasa, ada pro dan kontra.
Gunakan
std::reverse_iterator
:operator>()
std::greater<int>()
Gunakan
std::greater
saat:Adapun kinerja, kedua metode sama-sama efisien. Saya mencoba patokan berikut:
Dengan baris perintah ini:
std::greater
demostd::reverse_iterator
demoPengaturan waktunya sama. Valgrind melaporkan jumlah cache yang sama.
sumber
Saya tidak berpikir Anda harus menggunakan salah satu metode dalam pertanyaan karena keduanya membingungkan, dan yang kedua rapuh seperti yang disarankan Mehrdad.
Saya akan menganjurkan berikut ini, karena terlihat seperti fungsi perpustakaan standar dan memperjelas niatnya:
sumber
std::greater
komparator ....Anda dapat menggunakan yang pertama atau mencoba kode di bawah ini yang sama-sama efisien
sumber