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

C++ HashMap 순회 중 키로 항목 제거하는 방법

이 튜토리얼에서는 C++에서 HashMap(std::map)을 순회하는 도중에 키를 이용해 특정 항목을 제거하는 방법을 알아봅니다. 먼저 예시를 통해 문제 상황을 확인해 보겠습니다.

입력: HashMap: { 1: "Tutorials",
                 2: "Tutorials",
                 3: "Point" }, key=1

출력: HashMap: { 2: "Tutorials",
                 3: "Point" }

설명: 키 '1'에 해당하는 첫 번째 요소가 제거되었습니다.

입력: HashMap: { 1: "God",
                 2: "is",
                 3: "Great" }, key=2

출력: HashMap: { 1: "God",
                 3: "Great" }

해결 방법 접근

C++에서는 .erase() 함수에 키를 전달하는 것만으로 해당 항목을 손쉽게 제거할 수 있습니다. 하지만 이번 문제는 컨테이너를 순회(iteration)하는 도중에 조건에 맞는 키를 찾아 제거해야 하므로, 반복자(iterator)도 함께 활용해야 합니다.

핵심 아이디어는 HashMap의 모든 키를 하나씩 검사하면서, 현재 반복자가 가리키는 키가 삭제 대상 키와 일치하는지 확인하고, 일치할 경우 그 항목을 지우는 것입니다.

예제 1: 순회 없이 키로 제거하기

가장 단순한 방법은 반복 없이 키만으로 요소를 제거하는 것입니다. 아래 코드는 erase(key)를 직접 호출하는 예제입니다.

#include<iostream>
#include<map> // map 연산을 위한 헤더
using namespace std;
int main(){
    // HashMap 생성
    map< int, string > mp;
    // HashMap에 키-값 쌍 삽입
    mp[1]="Tutorials";
    mp[2]="Tutorials";
    mp[3]="Point";
    int key = 2;
    // 반복자 생성
    map<int, string>::iterator it;
    // 삭제 전 HashMap 출력
    cout<< "HashMap before Deletion:\n";
    for (it = mp.begin(); it != mp.end(); ++it)
        cout << it->first << "->" << it->second << endl;
    // 키로 요소 제거
    mp.erase(key);
    // 삭제 후 HashMap 출력
    cout<< "HashMap After Deletion:\n";
    for (it = mp.begin(); it != mp.end(); ++it)
        cout << it->first << "->" << it->second << endl;
    return 0;
}

실행 결과

HashMap before Deletion:
1->Tutorials
2->Tutorials
3->Point

HashMap After Deletion:
1->Tutorials
3->Point

예제 2: 순회하면서 요소 제거하기

이번에는 반복문으로 HashMap을 순회하면서 조건에 맞는 키를 발견한 즉시 해당 항목을 제거합니다. 여기서 한 가지 주의할 점이 있습니다. erase()가 호출되면 해당 위치의 반복자는 무효화되므로, 무효화된 반복자를 계속 사용하면 정의되지 않은 동작(undefined behavior)이 발생할 수 있습니다.

C++11부터 map::erase(iterator)는 삭제된 요소의 다음 반복자를 반환하므로, 이 반환값을 활용하면 순회와 삭제를 안전하게 동시에 처리할 수 있습니다.

#include<iostream>
#include<map> // map 연산을 위한 헤더
using namespace std;
int main(){
    // HashMap 생성
    map< int, string > mp;
    // HashMap에 키-값 쌍 삽입
    mp[1]="Tutorials";
    mp[2]="Tutorials";
    mp[3]="Point";
    int key = 2;
    // 반복자 생성
    map<int, string>::iterator it;
    // 삭제 전 HashMap 출력
    cout<< "HashMap before Deletion:\n";
    for (it = mp.begin(); it != mp.end(); ++it)
        cout << it->first << "->" << it->second << endl;
    // HashMap을 순회하며 조건에 맞는 키 제거
    for (it = mp.begin(); it != mp.end(); ) {
        if (it->first == key)
            it = mp.erase(it); // erase는 다음 유효한 반복자를 반환
        else
            ++it;
    }
    // 삭제 후 HashMap 출력
    cout<< "HashMap After Deletion:\n";
    for (it = mp.begin(); it != mp.end(); ++it)
        cout << it->first << "->" << it->second << endl;
    return 0;
}

실행 결과

HashMap before Deletion:
1->Tutorials
2->Tutorials
3->Point

HashMap After Deletion:
1->Tutorials
3->Point

정리

이 튜토리얼에서는 C++에서 HashMap(map)의 항목을 키로 제거하는 두 가지 방법을 살펴보았습니다. 하나는 순회 없이 erase(key)로 바로 삭제하는 방법이고, 다른 하나는 반복문으로 순회하면서 조건에 맞는 항목을 제거하는 방법입니다. 특히 순회 중 삭제 시에는 반복자 무효화 문제를 피하기 위해 it = mp.erase(it) 패턴을 사용하는 것이 안전합니다. 같은 원리는 C, Java, Python 등 다른 프로그래밍 언어에서도 유사하게 적용됩니다. 이 튜토리얼이 도움이 되었기를 바랍니다.