Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ STL list::unique() 함수로 중복 요소 제거하기 – 문법과 예제 총정리

C++ STL에서 list 컨테이너가 제공하는 unique() 함수는 리스트 안에 포함된 중복 요소들을 효율적으로 제거해 주는 강력한 도구입니다. 이 글에서는 unique() 함수의 개념, 문법, 그리고 다양한 예제 코드를 통해 실제 동작 방식까지 자세히 살펴보겠습니다.

C++ STL에서 리스트(List)란?

리스트(list)는 시퀀스 내 어느 위치에서든 상수 시간(O(1))에 삽입과 삭제가 가능한 컨테이너입니다. 리스트는 이중 연결 리스트(doubly linked list)로 구현되어 있으며, 메모리가 연속적이지 않은 비연속 할당(non-contiguous allocation) 방식을 사용합니다.

이러한 특성 덕분에 리스트는 배열(array), 벡터(vector), 덱(deque)보다 임의 위치에서의 요소 삽입·추출·이동 성능이 뛰어납니다. 다만 특정 요소에 직접 접근(random access)하는 속도는 느린 편입니다.

리스트는 forward_list와 유사하지만, forward_list는 단일 연결 리스트(singly linked list)로 앞쪽 방향으로만 순회(iterate)할 수 있다는 차이점이 있습니다.

unique() 함수란?

listunique() 함수는 리스트에 존재하는 모든 중복 요소를 제거하고, 각 값이 한 번씩만 남도록 만듭니다. 기본형으로는 인접한 중복 값을 비교하지만, 이진 술어(binary predicate)를 인자로 전달하면 사용자가 정의한 기준으로 중복 여부를 판단할 수 있습니다.

문법

list_name.unique(binary_predicate_name);

이진 술어(Binary Predicate)의 문법

bool 함수이름(data_type a, data_type b);

매개변수

unique() 함수는 하나의 매개변수를 받습니다. 이 매개변수는 두 요소가 같다고 판단되어야 할 때 true를 반환하는 이진 술어입니다. 술어가 true를 반환하면 해당 두 요소는 중복으로 간주되어 제거됩니다.

예제 입출력

입력 List − 2 2 6 7 9 9 9 10 5 5
출력 New List − 2 5 6 7 9 10

입력 List − 3.14 5.56 7.62 9.00 0.45 7.62 9.00 7.62 0.45 3.00
출력 New List − 0.45 3.00 3.14 5.56 7.62 9.00

구현 접근 방법

  • 먼저 이진 술어(binary predicate) 함수를 작성합니다.

  • 그다음 리스트를 초기화합니다.

  • unique() 함수를 호출하여 중복을 제거합니다.

  • 마지막으로 unique 연산 후의 리스트를 출력합니다.

위와 같은 접근 방식을 사용하면 리스트에서 원하는 기준의 중복 요소를 손쉽게 제거할 수 있습니다.

예제 1: 정수(int) 리스트에서 중복 제거

// C++ 코드: STL에서 list unique() 함수의 동작을 보여줍니다
#include <iostream>
#include <list>
#include <cstdlib>
using namespace std;

// 이진 술어(binary predicate) 함수
bool cmp(int a, int b) {
    return (abs(a) == abs(b));
}

int main() {
    list<int> lst = { 13, 14, 13, 19, 20, 19, 15, 19, 20, 15, 15 };

    // 리스트 출력
    cout << "Elements in List: ";
    for (auto x = lst.begin(); x != lst.end(); ++x)
        cout << *x << " ";

    // unique() 함수 호출
    lst.unique(cmp);

    // unique 연산 후 새 리스트 출력
    cout << "\nList after unique operation: ";
    for (auto x = lst.begin(); x != lst.end(); ++x)
        cout << *x << " ";

    return 0;
}

출력 결과

위 코드를 실행하면 다음과 같은 결과가 출력됩니다.

Input - Elements in List: 13 14 13 19 20 19 15 19 20 15
Output - List after unique operation: 13 14 15 19 20

이 예제에서는 절댓값이 같은 요소들을 중복으로 판단하는 술어를 사용했으며, 그 결과 각 값이 한 번씩만 남은 리스트가 생성되었습니다.

예제 2: 실수(float) 리스트에서 중복 제거

// C++ 코드: STL에서 list unique() 함수의 동작을 보여줍니다
#include <iostream>
#include <list>
#include <cmath>
using namespace std;

// 이진 술어(binary predicate) 함수
bool cmp(float a, float b) {
    return (fabs(a) == fabs(b));
}

int main() {
    list<float> lst = { 3.14, 5.56, 7.62, 9.00, 0.45, 7.62, 9.00, 7.62, 0.45, 3.00 };

    // 리스트 출력
    cout << "Elements in List: ";
    for (auto x = lst.begin(); x != lst.end(); ++x)
        cout << *x << " ";

    // unique() 함수 호출
    lst.unique(cmp);

    // unique 연산 후 새 리스트 출력
    cout << "\nList after unique operation: ";
    for (auto x = lst.begin(); x != lst.end(); ++x)
        cout << *x << " ";

    return 0;
}

출력 결과

위 코드를 실행하면 다음과 같은 결과가 출력됩니다.

Input - Elements in List: 3.14 5.56 7.62 9.00 0.45 7.62 9.00 7.62 0.45 3.00
Output - List after unique operation: 0.45 3.00 3.14 5.56 7.62 9.00

마무리

C++ STL의 list::unique() 함수는 별도의 임시 컨테이너 없이 리스트 내부에서 직접 중복을 제거할 수 있어 매우 효율적입니다. 특히 이진 술어를 활용하면 단순한 값 비교를 넘어 사용자 정의 기준(예: 절댓값 비교 등)으로 중복을 판단할 수 있어, 다양한 상황에서 유연하게 활용할 수 있습니다.