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>가 있고 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);
operator+
되어 있지 반드시 같은 다른 컨테이너 유형에 대한 반복자에 대해 정의 list<T>::iterator
(당신이 할 수없는 list.begin() + 2
온 std::list
, 당신이 사용해야 std::advance
하는 경우)
std::find_if
std :: vector의 지우기 메소드가 과부하되어 있으므로 호출하는 것이 더 명확합니다.
vec.erase(vec.begin() + index);
단일 요소 만 지우고 싶을 때
vec.begin()
유효한 요소를 얻습니다 .
vec.erase(0)
작동하지 않지만 vec.erase(vec.begin()+0)
(또는 +0없이) 언급 하지 않았기를 바랍니다 . 그렇지 않으면 내가 여기 온 이유입니다, 일치 함수 호출을 얻을
vec.erase(0)
는 0
널 포인터 상수로 해석 될 경우 실제로 컴파일 될 수 있습니다 .
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);
}
template <typename T> void remove(std::vector<T>& vec, size_t pos) { vec.erase(vec.begin + pos); }
나는 개인적으로 관심을 가지지 않고이 질문이 얻을 수있는 최상의 결과를 돌려주는 것이 더 낫다는 말이 아닙니다.
vector<T>::iterator
는 랜덤 액세스 반복자이므로, 버전이 양호하고 약간 더 명확 할 수 있습니다. 그러나 컨테이너를 랜덤 액세스 반복자를 지원하지 않는 다른 컨테이너로 변경하면 Max가 게시 한 버전이 제대로 작동합니다
실제로이 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;
}
목록 순서는 중요하지 않으므로 목록의 마지막 요소를 가져 와서 제거하려는 항목의 맨 위에 복사 한 다음 마지막 항목을 팝업하여 삭제하십시오.
iterator + index
해당 인덱스에서 반복자 위치를 실제로 돌려주는 가정에 의존하지 않으며 모든 반복 가능한 컨테이너에 해당되는 것은 아닙니다. 백 포인터를 이용하면 선형 대신 복잡성이 일정합니다.
unordered_remove
하고 unordered_remove_if
이되었습니다 내가하는이 일 :) 종종 더 많은 일이 일어나고, 그것을 놓친하지 않는 한 ...
std::remove
제거 할 모든 요소가 끝날 수 있도록 컨테이너를 재정렬합니다. C ++ 17을 사용하는 경우 이와 같이 수동으로 수행 할 필요가 없습니다.
std::remove
도움이 되나요? cppreference는 C ++ 17에서도 모든 remove
오버로드에 술어가 필요하고 인덱스를 취하지 않는다고 주장합니다.
큰 벡터 (크기> 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));
여기에서 당신의 가치를 제거 할 것입니다. 감사
가장 빠른 방법 (시간 복잡성으로 컨테스트를 프로그래밍하는 경우 () = 상수)
1 초 안에 100M 항목을 지울 수 있습니다.
vector<int> it = (vector<int>::iterator) &vec[pos];
vec.erase(it);
가장 읽기 쉬운 방법 :
vec.erase(vec.begin() + pos);
vector<int>::iterator
로 반드시 동일하지 않습니다int *