C++에서 std::map과 std::pair를 사용한 투명 검색
투명 검색이란 키를 직접 사용하는 대신 키를 포함하는 객체를 사용하여 std::map
에서 값을 검색하는 것을 의미합니다. 이는 std::map
의 find()
메서드를 사용하여 수행할 수 있습니다.
다음은 std::pair
를 키로 사용하는 std::map
을 만들고 투명 검색을 수행하는 예제입니다.
#include <iostream>
#include <map>
#include <utility>
using namespace std;
int main() {
// `std::pair`를 키로 사용하는 `std::map`을 만듭니다.
map<pair<int, int>, string> my_map;
// `std::map`에 키-값 쌍을 추가합니다.
my_map[{1, 2}] = "Hello";
my_map[{3, 4}] = "World";
// `std::pair`를 사용하여 `std::map`에서 값을 검색합니다.
auto it = my_map.find({1, 2});
// 값이 found되면 출력합니다.
if (it != my_map.end()) {
cout << it->second << endl;
} else {
cout << "Key not found" << endl;
}
return 0;
}
이 예제에서 my_map
은 std::pair
를 키로 사용하는 std::map
입니다. my_map
에 두 개의 키-값 쌍이 추가됩니다. 그런 다음 {1, 2}
키를 사용하여 my_map
에서 값을 검색합니다. 키가 발견되면 값 "Hello"가 출력됩니다.
투명 검색을 사용하는 이점:
- 코드를 더 간결하게 만들 수 있습니다.
- 키를 직접 사용하는 대신 키를 포함하는 객체를 사용하여 검색할 수 있습니다.
투명 검색을 사용할 때 주의해야 할 점:
- 키를 포함하는 객체는 비교 가능해야 합니다.
예제 코드
#include <iostream>
#include <map>
#include <utility>
using namespace std;
class Person {
public:
string name;
int age;
Person(string name, int age) {
this->name = name;
this->age = age;
}
bool operator==(const Person& other) const {
return this->name == other.name && this->age == other.age;
}
};
int main() {
// `Person` 객체를 키로 사용하는 `std::map`을 만듭니다.
map<Person, string> my_map;
// `std::map`에 키-값 쌍을 추가합니다.
my_map[{Person("John", 30)}] = "Hello";
my_map[{Person("Jane", 25)}] = "World";
// `Person` 객체를 사용하여 `std::map`에서 값을 검색합니다.
auto it = my_map.find({Person("John", 30)});
// 값이 found되면 출력합니다.
if (it != my_map.end()) {
cout << it->second << endl;
} else {
cout << "Key not found" << endl;
}
return 0;
}
이 예제는 다음과 같은 점을 보여줍니다.
std::map
은 사용자 정의 클래스를 키로 사용할 수 있습니다.- 키를 비교하기 위해
operator==
연산자를 오버라이드해야 합니다.
투명 검색을 위한 대체 방법
std::unordered_map 사용:
std::unordered_map
은 std::map
과 유사하지만 해시 테이블을 사용하여 키-값 쌍을 저장합니다. 이는 std::map
보다 검색 속도가 빠를 수 있지만 키를 비교하기 위해 해시 함수를 사용해야 합니다.
#include <iostream>
#include <unordered_map>
#include <utility>
using namespace std;
class Person {
public:
string name;
int age;
Person(string name, int age) {
this->name = name;
this->age = age;
}
bool operator==(const Person& other) const {
return this->name == other.name && this->age == other.age;
}
size_t hash() const {
// 해시 함수를 구현합니다.
return hash<string>()(name) ^ hash<int>()(age);
}
};
int main() {
// `Person` 객체를 키로 사용하는 `std::unordered_map`을 만듭니다.
unordered_map<Person, string> my_map;
// `std::unordered_map`에 키-값 쌍을 추가합니다.
my_map[{Person("John", 30)}] = "Hello";
my_map[{Person("Jane", 25)}] = "World";
// `Person` 객체를 사용하여 `std::unordered_map`에서 값을 검색합니다.
auto it = my_map.find({Person("John", 30)});
// 값이 found되면 출력합니다.
if (it != my_map.end()) {
cout << it->second << endl;
} else {
cout << "Key not found" << endl;
}
return 0;
}
std::vector와 std::find_if 사용:
std::vector
와 std::find_if
를 사용하여 키-값 쌍을 저장하고 검색할 수 있습니다. 이 방법은 std::map
보다 느릴 수 있지만 키를 비교하기 위해 해시 함수를 사용할 필요가 없습니다.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Person {
public:
string name;
int age;
Person(string name, int age) {
this->name = name;
this->age = age;
}
bool operator==(const Person& other) const {
return this->name == other.name && this->age == other.age;
}
};
int main() {
// `Person` 객체를 저장하는 `std::vector`를 만듭니다.
vector<pair<Person, string>> my_vector;
// `std::vector`에 키-값 쌍을 추가합니다.
my_vector.push_back({{Person("John", 30)}, "Hello"});
my_vector.push_back({{Person("Jane", 25)}, "World"});
// `Person` 객체를 사용하여 `std::vector`에서 값을 검색합니다.
auto it = find_if(my_vector.begin(), my_vector.end(), [](const pair<Person, string>& p) {
return p.first == Person("John", 30);
});
// 값이 found되면 출력합니다.
if (it != my_vector.end()) {
cout << it->second << endl;
} else {
cout << "Key not found" << endl;
}
return 0;
}
사용자 정의 컨테이너 사용:
사용자 정의 컨테이너를 만들어 키-값 쌍을 저장하고 검색할 수 있습니다. 이 방법은 가장 유연하지만 가장 많은 작업이 필요합니다.
어떤 방법을 사용해야 할까요?
사용해야 하는 방법은 특정 요구 사항에 따라 다릅니다. 다음 사항을 고려해야 합니다.
- 검색 속도
- 키 비교 방법
- 필요한
c++ std stdmap