เหตุใดฉันจึงได้ผลลัพธ์ที่แตกต่างกันถ้าแทนที่จะเป็น x ฉันส่งองค์ประกอบอาร์เรย์โดยตรง ar [0] ในฟังก์ชัน std :: remove [ซ้ำ]

Aug 19 2020
#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;
}

ทำไมฉันจะได้รับผลที่แตกต่างกันถ้าแทนของxฉันผ่านโดยตรงar[0]ในstd::removeฟังก์ชั่น?

xและar[0]มีค่าเท่ากัน

คำตอบ

3 largest_prime_is_463035818 Aug 19 2020 at 13:09

เหตุผลก็คือstd::removeใช้พารามิเตอร์สุดท้ายโดยการอ้างอิง จากcppreference :

เนื่องจาก std :: remove รับค่าตามการอ้างอิงจึงอาจมีลักษณะการทำงานที่ไม่คาดคิดหากเป็นการอ้างอิงถึงองค์ประกอบของช่วง [แรกสุดท้าย)

เป็นเรื่องยุ่งยากเล็กน้อยเนื่องจากพารามิเตอร์ถูกส่งผ่านเป็นconstข้อมูลอ้างอิง:

template< class ForwardIt, class T >
ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );

อย่างไรก็ตามเพียงเพราะar[0]ผ่านconstการอ้างอิงไม่ได้หมายความว่าar[0]ไม่สามารถแก้ไขโดยวิธีอื่นได้ ในกรณีนี้จะมีการปรับเปลี่ยนผ่าน/first lastที่จริงผมไม่สามารถคิดกรณีที่มันจะเป็น "OK" ที่จะมีภายในองค์ประกอบเป็น[first, last)value

สำหรับภาพประกอบให้พิจารณาว่าคุณได้ผลลัพธ์ที่ไม่ถูกต้องar[0]เหมือนกับที่คุณประกาศxว่าเป็นข้อมูลอ้างอิง:

int& x=ar[0];
ar.erase(remove(ar.begin(),ar.end(),x),ar.end());

ที่นี่xจะถูกส่งเป็นconstข้อมูลอ้างอิง ar[0]แต่ขั้นตอนวิธีการไม่ปรับเปลี่ยน