Mengapa saya mendapatkan hasil yang berbeda jika alih-alih x saya langsung meneruskan elemen array ar [0] dalam fungsi std :: remove? [duplikat]
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
int main()
{
vector<int> ar = {1, 2, 2, 2, 3, 4, 5, 5, 5, 6, 7};
vector<int> sum;
int n = ar.size();
for (int i = 0; i < n; i++)
{
int x = ar[0];
int frq = count(ar.begin(), ar.end(), x);
int q = frq / 2;
sum.push_back(q);
ar.erase(remove(ar.begin(), ar.end(), x), ar.end()); // Doubt
}
int count = 0;
int n1 = sum.size();
for (int i = 0; i < n1; i++)
{
count = count + sum[i];
}
cout << count;
}
Mengapa saya mendapatkan hasil yang berbeda jika bukan x
saya langsung lulus ar[0]
di std::remove
fungsi?
x
dan ar[0]
memiliki nilai yang sama.
Jawaban
Alasannya adalah karena std::remove
mengambil parameter terakhir sebagai referensi. Dari cppreference :
Karena std :: remove mengambil nilai dengan referensi, ia bisa memiliki perilaku yang tidak terduga jika ia merujuk ke elemen rentang [pertama, terakhir).
Agak rumit, karena parameter diteruskan sebagai const
referensi:
template< class ForwardIt, class T > ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );
Namun, hanya karena ar[0]
diteruskan sebagai const
referensi tidak berarti bahwa ar[0]
tidak dapat dimodifikasi dengan cara lain. Dalam hal ini diubah melalui first
/ last
. Sebenarnya saya tidak dapat memikirkan kasus di mana akan "baik" untuk memiliki elemen di dalamnya [first, last)
sebagai value
.
Sebagai ilustrasi, pertimbangkan bahwa Anda mendapatkan keluaran yang salah yang sama ar[0]
seperti jika Anda menyatakan x
sebagai referensi:
int& x=ar[0];
ar.erase(remove(ar.begin(),ar.end(),x),ar.end());
Ini x
diteruskan sebagai const
referensi, tetapi algoritme memang memodifikasi ar[0]
.