Jawaban:
Saya lebih suka it - vec.begin()
justru karena alasan sebaliknya yang diberikan oleh Naveen: jadi itu tidak akan dikompilasi jika Anda mengubah vektor menjadi daftar. Jika Anda melakukan ini selama setiap iterasi, Anda bisa dengan mudah mengubah algoritma O (n) menjadi algoritma O (n ^ 2).
Pilihan lain, jika Anda tidak melompat-lompat di dalam wadah selama iterasi, akan menjaga indeks sebagai penghitung lingkaran kedua.
Catatan: it
adalah nama umum untuk iterator penampung std::container_type::iterator it;
,.
it
?
std::container_type::iterator it;
std::list
tidak menawarkan akses langsung ke elemen berdasarkan posisi mereka, jadi jika Anda tidak dapat melakukannya list[5]
, Anda seharusnya tidak dapat melakukannya list.begin() + 5
.
Saya lebih suka std::distance(vec.begin(), it)
karena akan memungkinkan saya untuk mengubah wadah tanpa perubahan kode. Misalnya, jika Anda memutuskan untuk menggunakan std::list
alih-alih std::vector
yang tidak memberikan iterator akses acak, kode Anda masih akan dikompilasi. Karena std :: distance mengambil metode optimal tergantung pada sifat iterator Anda tidak akan mengalami penurunan kinerja.
vec
adalah berita buruk. Jika kode tersebut ditulis ulang menjadi generik, dengan menggunakan tipe wadah sebagai parameter templat, saat itulah kita dapat (dan harus) berbicara tentang penanganan iterator non-akses acak ;-)
vec
juga berita buruk.
Seperti yang ditunjukkan UncleBens dan Naveen, ada alasan bagus untuk keduanya. Yang mana yang "lebih baik" tergantung pada perilaku apa yang Anda inginkan: Apakah Anda ingin menjamin perilaku waktu-konstan, atau Anda ingin kembali ke waktu linier bila diperlukan?
it - vec.begin()
membutuhkan waktu yang konstan, tetapi operator -
hanya didefinisikan pada iterator akses acak, jadi kode tidak akan dikompilasi sama sekali dengan iterator daftar, misalnya.
std::distance(vec.begin(), it)
bekerja untuk semua jenis iterator, tetapi hanya akan menjadi operasi waktu konstan jika digunakan pada iterator akses acak.
Tidak ada yang "lebih baik". Gunakan yang melakukan apa yang Anda butuhkan.
Saya suka yang ini:, it - vec.begin()
karena bagi saya itu jelas mengatakan "jarak dari awal". Dengan iterator kita terbiasa berpikir dalam hal aritmatika, jadi -
tandanya adalah indikator yang paling jelas di sini.
distance
?
it++
dan bukan sesuatu seperti itu std::increment(it)
, bukan? Bukankah itu juga dianggap kurang jelas?
++
Operator didefinisikan sebagai bagian dari urutan STL bagaimana kita kenaikan iterator. std::distance
menghitung jumlah elemen antara elemen pertama dan terakhir. Fakta bahwa -
operator bekerja hanyalah sebuah kebetulan.
Jika Anda sudah dibatasi / hardcode algoritma Anda untuk menggunakan a std::vector::iterator
dan std::vector::iterator
hanya, tidak masalah metode mana yang Anda akan gunakan. Algoritme Anda sudah dikonkretkan melampaui titik di mana memilih satu dari yang lain dapat membuat perbedaan. Mereka berdua melakukan hal yang persis sama. Ini hanya masalah preferensi pribadi. Saya pribadi akan menggunakan pengurangan eksplisit.
Sebaliknya, jika Anda ingin mempertahankan tingkat umum yang lebih tinggi dalam algoritme Anda, yaitu, untuk memungkinkan kemungkinan bahwa suatu hari di masa depan itu dapat diterapkan ke beberapa jenis iterator lain, maka metode terbaik tergantung pada niat Anda. . Itu tergantung pada seberapa ketat Anda ingin berkaitan dengan jenis iterator yang dapat digunakan di sini.
Jika Anda menggunakan pengurangan eksplisit, algoritme Anda akan dibatasi untuk kelas iterator yang agak sempit: iterator akses-acak. (Ini adalah apa yang Anda dapatkan sekarang dari std::vector
)
Jika Anda menggunakan distance
, algoritma Anda akan mendukung kelas iterator yang lebih luas: input iterator.
Tentu saja, menghitung distance
untuk iterator non-akses-acak pada umumnya merupakan operasi yang tidak efisien (sementara, sekali lagi, untuk akses-acak itu seefisien pengurangan). Terserah Anda untuk memutuskan apakah algoritma Anda masuk akal untuk iterator non-acak-akses, efisiensi-bijaksana. Jika kerugian yang dihasilkan dalam efisiensi sangat menghancurkan hingga membuat algoritma Anda sama sekali tidak berguna, maka Anda sebaiknya tetap berpegang pada pengurangan, sehingga melarang penggunaan yang tidak efisien dan memaksa pengguna untuk mencari solusi alternatif untuk jenis iterator lainnya. Jika efisiensi dengan iterator non-akses acak masih dalam rentang yang dapat digunakan, maka Anda harus menggunakan distance
dan mendokumentasikan fakta bahwa algoritma ini bekerja lebih baik dengan iterator akses acak.
Menurut http://www.cplusplus.com/reference/std/iterator/distance/ , karena vec.begin()
merupakan iterator akses acak , metode jarak menggunakan -
operator.
Jadi jawabannya adalah, dari sudut pandang kinerja, itu sama, tetapi mungkin menggunakan distance()
lebih mudah untuk dipahami jika ada yang harus membaca dan memahami kode Anda.
Saya akan menggunakan -
varian std::vector
hanya - cukup jelas apa yang dimaksud, dan kesederhanaan operasi (yang tidak lebih dari pengurangan pointer) diekspresikan oleh sintaks ( distance
, di sisi lain, terdengar seperti pythagoras pada bacaan pertama, bukan?). Seperti yang ditunjukkan oleh UncleBen, ini -
juga bertindak sebagai pernyataan statis jika vector
suatu kasus diubah secara tidak sengaja list
.
Juga saya pikir ini jauh lebih umum - tidak ada angka untuk membuktikannya. Argumen utama: it - vec.begin()
lebih pendek dalam kode sumber - lebih sedikit pekerjaan mengetik, lebih sedikit ruang yang digunakan. Karena jelas bahwa jawaban yang tepat untuk pertanyaan Anda menjadi masalah selera, ini juga bisa menjadi argumen yang valid.
Berikut adalah contoh untuk menemukan "semua" kejadian 10 beserta indeksnya. Kupikir ini akan sangat membantu.
void _find_all_test()
{
vector<int> ints;
int val;
while(cin >> val) ints.push_back(val);
vector<int>::iterator it;
it = ints.begin();
int count = ints.size();
do
{
it = find(it,ints.end(), 10);//assuming 10 as search element
cout << *it << " found at index " << count -(ints.end() - it) << endl;
}while(++it != ints.end());
}