Computer Language/C & C++

[C++] Unique 함수

HONGGG 2023. 11. 15. 23:45

Unique

중복된 값을 제거하고 정렬한다.

 

Unique함수는 프로그래머스를 풀다 발견한 재밌는 함수이다.

헤더 C++ algorithm
함수명 unique ForwardIterator unique (ForwardIterator first, ForwardIterator last, BinaryPredicate pred);
매개변수
ForwardIterator first 반복자 시작 위치
ForwardIterator last 반복자 종료 위치
BinaryPredicate pred 명명된 요구 사항
반환값 ForwardIterator 가장 마지막으로 중복처리를 한 반복자 위치

 

이 함수는 특정 컨테이너의 중복된 값들을 하나로 만든다.

 

중복된 값들을 모두 정리하면 필히 원래 크기보다 줄어들게 되는데, unique는 리스트의 크기를 줄이지 않는다.

오히려 각 컨테이너들이 알아서 처리할 수 있도록 중복 처리를 끝낸 마지막 위치를 반환한다.

 

다시 말하지만 연속된 중복 값에 대한 연산처리를 한다. 리스트의 크기는 줄이지 않는다. 이게 무슨 말이냐 하니....

vector<int> v1 = {5, -5, 5, 5, -5, 5, -5, 5, -5, 4, 4, 4, 4, 7}; // 14개의 원소를 담은 벡터

// 중복 제거
vector<int>::iterator dupplication = unique ( v1.begin( ), v1.end( ) );
// 결과 : (5 -5 5 -5 5 -5 5 -5 4 7) 4 4 4 7
// 중복 처리를 끝낸 결과물로 10개의 원소만 남는다.
// 원래 크기가 14이기 때문에 10개 뒤 원소는 원래 값을 가진채 남아있다.
// dupplication 반복자는 unique로 중복처리된 마지막 위치를 가리킨다.

// dupplication을 이용한 잔여 원소 제거 (10~13원소 제거)
v1.erase(dupplication, v1.end());
// 결과 : 5 -5 5 -5 5 -5 5 -5 4 7
  1. 14개의 원소를 가진 v1 벡터를 선언한다.
  2. unique로 중복처리를 하지만 앞뒤로 연속되지 않은 자리는 중복처리하지 않는다.
  3. dupplication 반복자에 중복처리한 마지막 자리 정보를 넘긴다.
  4. erase함수를 통해 마지막 자리부터 끝자리까지 지워버린다.

예제코드

#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
#include <ostream>

using namespace std;

// 음수를 모두 양수로 변환하여 중복 값인지 확인
bool mod_equal ( int elem1, int elem2 )
{
    if ( elem1 < 0 )
        elem1 = - elem1;
    if ( elem2 < 0 )
        elem2 = - elem2;
    return elem1 == elem2;
};

int main()
{
    vector<int> v1 = {5, -5, 5, -5, 5, -5, 5, -5, 4, 4, 4, 4, 7};
    vector<int>::iterator v1_Iter1, v1_Iter2, v1_Iter3;
    vector<int>::iterator v1_NewEnd1, v1_NewEnd2, v1_NewEnd3;

    cout << "Vector : " ;
    for ( v1_Iter1 = v1.begin( ) ; v1_Iter1 != v1.end( ) ; v1_Iter1++ )
        cout << *v1_Iter1 << " ";
    cout << endl;

    // 중복 제거
    v1_NewEnd1 = unique ( v1.begin( ), v1.end( ) );
    cout << "Removing duplicates : " ;
    for ( v1_Iter1 = v1.begin( ) ; v1_Iter1 != v1_NewEnd1 ; v1_Iter1++ )
        cout << *v1_Iter1 << " ";
    cout << endl;
	
    // 모든 음수를 양수로 변환하여 중복제거
    v1_NewEnd2 = unique ( v1.begin( ), v1_NewEnd1 , mod_equal );
    cout << "Removing negative duplicates : ";
    for ( v1_Iter2 = v1.begin( ) ; v1_Iter2 != v1_NewEnd2 ; v1_Iter2++ )
        cout << *v1_Iter2 << " ";
    cout << endl;

    // 각 원소가 더 큰 원소의 앞에 있다면 제거
    v1_NewEnd3 = unique ( v1.begin( ), v1_NewEnd2, greater<int>( ) );
    cout << "Removing greater : ";
    for ( v1_Iter3 = v1.begin( ) ; v1_Iter3 != v1_NewEnd3 ; v1_Iter3++ )
        cout << *v1_Iter3 << " ";
    cout << endl;
}
Vector : 5 -5 5 -5 5 -5 5 -5 4 4 4 4 7 
Removing duplicates : 5 -5 5 -5 5 -5 5 -5 4 7 
Removing negative duplicates : 5 4 7 
Removing greater : 5 7

참고자료