Programing

인덱스로 std :: vector <>에서 요소를 지우려면 어떻게합니까?

lottogame 2020. 2. 16. 19:14
반응형

인덱스로 std :: vector <>에서 요소를 지우려면 어떻게합니까?


std :: vector <int>가 있고 n 번째 요소를 삭제하고 싶습니다. 어떻게해야합니까?

std::vector<int> vec;

vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);

vec.erase(???);

단일 요소를 삭제하려면 다음을 수행하십시오.

std::vector<int> vec;

vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);

// Deletes the second element (vec[1])
vec.erase(vec.begin() + 1);

또는 한 번에 둘 이상의 요소를 삭제하려면 다음을 수행하십시오.

// Deletes the second through third elements (vec[1], vec[2])
vec.erase(vec.begin() + 1, vec.begin() + 3);

std :: vector의 지우기 메소드가 과부하되었으므로 호출하는 것이 더 명확합니다.

vec.erase(vec.begin() + index);

단일 요소 만 지우고 싶을 때


template <typename T>
void remove(std::vector<T>& vec, size_t pos)
{
    std::vector<T>::iterator it = vec.begin();
    std::advance(it, pos);
    vec.erase(it);
}

erase방법은 두 가지 방식으로 사용됩니다.

  1. 단일 요소 지우기 :

    vector.erase( vector.begin() + 3 ); // Deleting the fourth element
    
  2. 요소 지우기 범위 :

    vector.erase( vector.begin() + 3, vector.begin() + 5 ); // Deleting from fourth element to sixth element
    

실제로이 erase기능은 두 가지 프로파일에서 작동합니다.

  • 단일 요소 제거

    iterator erase (iterator position);
    
  • 다양한 요소 제거

    iterator erase (iterator first, iterator last);
    

std :: vec.begin ()은 컨테이너의 시작을 표시하고 벡터에서 ith 요소를 삭제하려면 다음을 사용할 수 있습니다.

vec.erase(vec.begin() + index);

자세히 살펴보면 vec.begin ()은 벡터의 시작 위치에 대한 포인터 일 뿐이며 i 값을 추가하면 i 위치에 대한 포인터가 증가하므로 대신 i 번째 요소에 대한 포인터에 액세스 할 수 있습니다.

&vec[i]

그래서 우리는 쓸 수 있습니다 :

vec.erase(&vec[i]); // To delete the ith element

정렬되지 않은 벡터가있는 경우 정렬되지 않은 벡터를 활용하여 CPPCON의 Dan Higgins에서 본 것을 사용할 수 있습니다.

template< typename TContainer >
static bool EraseFromUnorderedByIndex( TContainer& inContainer, size_t inIndex )
{
    if ( inIndex < inContainer.size() )
    {
        if ( inIndex != inContainer.size() - 1 )
            inContainer[inIndex] = inContainer.back();
        inContainer.pop_back();
        return true;
    }
    return false;
}

목록 순서는 중요하지 않으므로 목록의 마지막 요소를 가져 와서 제거하려는 항목의 맨 위에 복사 한 다음 마지막 항목을 팝업하여 삭제하십시오.


큰 벡터 (크기> 100,000)로 작업하고 많은 요소를 삭제하려면 다음과 같이하십시오.

int main(int argc, char** argv) {

    vector <int> vec;
    vector <int> vec2;

    for (int i = 0; i < 20000000; i++){
        vec.push_back(i);}

    for (int i = 0; i < vec.size(); i++)
    {
        if(vec.at(i) %3 != 0)
            vec2.push_back(i);
    }

    vec = vec2;
    cout << vec.size() << endl;
}

이 코드는 vec의 모든 숫자를 3으로 나눌 수 없으며 vec2에 복사합니다. 그런 다음 vec2를 vec로 복사합니다. 꽤 빠릅니다. 20,000,000 개의 요소를 처리하는 데이 알고리즘은 0.8 초만 걸립니다!

나는 지우기 방법으로 똑같은 일을했으며 많은 시간이 걸립니다.

Erase-Version (10k elements)  : 0.04 sec
Erase-Version (100k elements) : 0.6  sec
Erase-Version (1000k elements): 56   sec
Erase-Version (10000k elements): ...still calculating (>30 min)

요소를 삭제하려면 다음 방법을 사용하십시오.

// declaring and assigning array1 
std:vector<int> array1 {0,2,3,4};

// erasing the value in the array
array1.erase(array1.begin()+n);

A에 대한 보다 폭 넓은 개요 당신은 방문 할 수 있습니다 : http://www.cplusplus.com/reference/vector/vector/erase/


나는 그것이 당신이 찾고있는 것이라고 믿고 있기 때문에 이것을 읽는 것이 좋습니다. https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom

예를 들어 사용하는 경우

 vec.erase(vec.begin() + 1, vec.begin() + 3);

벡터의 n 번째 요소를 지우지 만 두 번째 요소를 지우면 벡터의 다른 모든 요소가 이동하고 벡터 크기는 -1이됩니다. 벡터 크기 ()가 줄어들 기 때문에 벡터를 반복하면 문제가 될 수 있습니다. 이와 같은 문제가 발생하면 표준 C ++ 라이브러리에서 기존 알고리즘을 사용하는 것이 좋습니다. "remove"또는 "remove_if".

이것이 도움이 되었기를 바랍니다


이전 답변에서는 항상 서명 된 인덱스가 있다고 가정합니다 . 슬프게도, std::vector용도는 size_type색인에 대한, 그리고 difference_type당신이 "-Wconversion"이 친구가 활성화 된 경우, 반복자 산술 그들은 함께 작동하지 않도록. 이것은 서명 된 것과 서명되지 않은 것을 처리 할 수 ​​있고 질문에 대답하는 또 다른 방법입니다.

제거:

template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type>
void remove(std::vector<T> &v, I index)
{
    const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index);
    v.erase(iter);
}

가지다:

template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type>
T take(std::vector<T> &v, I index)
{
    const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index);

    auto val = *iter;
    v.erase(iter);

    return val;
}

벡터의 값으로 이것을 찾아서 요소를 삭제하려면 벡터 에서이 작업을 수행하면됩니다.

vector<int> ar(n);
ar.erase(remove(ar.begin(), ar.end()), (place your value here from vector array));

여기에서 당신의 가치를 제거 할 것입니다. 감사


이건 어때?

void squeeze(vector<int> &v)
{
    int j = 0;
    for (int i = 1; i < v.size(); i++)
        if (v[i] != v[j] && ++j != i)
            v[j] = v[i];
    v.resize(j + 1);
}

가장 빠른 방법 (시간 복잡성으로 컨테스트를 프로그래밍하는 경우 () = 상수)

1 초 안에 100M 항목을 지울 수 있습니다.

    vector<int> it = (vector<int>::iterator) &vec[pos];
    vec.erase(it);

가장 읽기 쉬운 방법 : vec.erase(vec.begin() + pos);

참고 URL : https://stackoverflow.com/questions/875103/how-do-i-erase-an-element-from-stdvector-by-index



반응형