std :: multiset에는 요소가 발견되면 하나의 샘플 (단일화 또는 복제) 만 지우는 함수 또는 알고리즘이 있습니다.


83

아마도 이것은 중복이지만 검색하는 것을 찾지 못했습니다 . 발견 된 값을 가진 모든 요소 erase(value)std::multiset대해 호출 되면 삭제됩니다. 내가 생각할 수있는 유일한 해결책은 다음과 같습니다.

std::multiset<int>::iterator hit(mySet.find(5));
if (hit!= mySet.end()) mySet.erase(hit);

이것은 괜찮지 만 더 나을 것이라고 생각했습니다. 어떤 아이디어?


22
이것은 완벽하게 합리적인 접근 방식입니다.
templatetypedef

이 접근 방식은 주어진 키 ( "5")가 중복되도록 보장합니까?
Arun

@ArunSaha : 아니요.하지만 중복이 아니라면 어쨌든 삭제하고 싶습니다. 내가 얻은 대답에서 나는 더 나은 해결책이 없다는 느낌을 받는다. 아마도 질문은 처음에 어리석은 것이었다. :-P
Martin

1
For multimap: 어떤 요소가 find반환 되는지에 대한 보장이 있습니까? (삽입 순서? 그런 삭제 후에도? 구현에 따라 다름?)
P Marecki

2
솔직히 가장 자주 사용되는 클래스에 속하지 않는 멀티 셋을 사용하는 동안에는 분명하지 않은 함정입니다.
Predelnik

답변:


32
auto itr = my_multiset.find(value);
if(itr!=my_multiset.end()){
    my_multiset.erase(itr);
}

나는 똑같은 것을 달성하는 더 깨끗한 방법이 있다고 상상할 것입니다. 그러나 이것은 작업을 완료합니다.


7
이것은 질문의 내용과 다르지 않습니다.
Troubadour

1
나는 동의한다! 말이 안 돼. 12 명의 다른 사람들이 답에서 유용한 것을 보았 기 때문에 나는 내가 미쳐 가지 않는다는 것을 압니다.
user2251346

6
당신이 : 다른 사람과 함께 미친 거라고 가능성을 간과하지 마십시오
Apollys 모니카 지원

15

이걸로 해봐:

multiset<int> s;
s.erase(s.lower_bound(value));

당신 value이 세트 에서 출구 를 확인할 수 있는 한. 작동합니다.


2
 if(my_multiset.find(key)!=my_multiset.end())
   my_multiset.erase(my_multiset.equal_range(key).first);

이것은 C ++의 다중 집합에서 단일 인스턴스를 제거하는 가장 좋은 방법입니다.


1
질문에서 제안한 솔루션과 비교하여 귀하의 코드는 비효율적 인 검색 대신 두 번의 검색 (find + equal_range)을 수행합니다
Martin

이것은 동일한 복잡성이기 때문에 나는이 대답을 매우 좋아합니다. 감사합니다
Crystal

1

나는 다음을 시도 할 것입니다.

equal_range()키와 동일한 요소의 범위를 찾기 위해 먼저 호출 합니다.

반환 된 범위가 비어 있지 않은 경우 erase()요소 범위 (즉, erase()두 개의 반복기를 사용하는 요소 )

  • 첫 번째 인수는 반환 된 범위 (즉, 하나의 과거 .first반환) 에서 두 번째 요소에 대한 반복자입니다.

  • 반환 범위 쌍 반복자로 두 번째 인수 .second하나.


templatetypedef 의 (감사합니다!) 주석 을 읽은 후 편집하십시오 .

하나 (모두와 반대되는) 중복을 제거해야하는 경우 : equal_range()에서 반환 된 쌍에 두 개 이상의 요소 erase()가있는 경우 반환 된 쌍의 .first를의 단일 반복자 버전으로 전달하여 첫 번째 요소가됩니다 erase().

의사 코드 :

pair<iterator, iterator> pit = mymultiset.equal_range( key );

if( distance( pit.first, pit.second ) >= 2 ) {
    mymultiset.erase( pit.first );
}

2
나는 질문이 모든 중복이 아니라 하나의 중복을 제거하는 것에 대해 묻는 것이라고 생각합니다.
templatetypedef

이것이 내 솔루션보다 빠른지 여부와 그렇다면 왜 그런지 알고 있습니까?
Martin

1

이것은 나를 위해 일했습니다.

multi_set.erase(multi_set.find(val));

val이 다중 세트에 존재하는 경우.


0

다음과 같이 할 수 있습니다.

multiset<int>::iterator it, it1;
it = myset.find(value);
it1 = it;
it1++;
myset.erase (it, it1);

1
지나침. "무순 다중 집합에서 제거 할 단일 요소를 가리키는 반복자."
Andrew

-3

사실 정답은 다음과 같습니다.

my_multiset.erase(my_multiset.find(value));

1
경우 값이 MULTISET에 존재하지 않는, 그것은 원인이 정의되지 않은 동작을 .
kien_coi_1997
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.