예시코드)
https://github.com/GbLeem/CPP_Study/tree/main/NoCode
67.cpp ~ 72.cpp
<까먹지 말기>
함수 앞의 const : 리턴 값을 상수화
함수 뒤의 const : 멤버 변수를 수정하지 않을거임
#include<iostream>
#include<set>
int main()
{
std::set<int>nums{ 1,2,3,4,5 };
nums.emplace(3);
nums.emplace(3);
nums.emplace(3);
nums.emplace(3);
//1 2 3 4 5 출력
nums.emplace(-1);
nums.emplace(100);
nums.emplace(2);
//-1 1 2 3 4 5 100 출력
for (const int num : nums)
{
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
#include<iostream>
#include<set>
struct customFn
{
bool operator() (const int lhs, const int rhs) const
{
return lhs > rhs; //내림차순 정렬
}
};
int main()
{
std::set<int, customFn>nums{ 1,2,3,4,5 };
nums.emplace(-1);
nums.emplace(100);
nums.emplace(2);
//100 5 4 3 2 1 -1 출력
for (const int num : nums)
{
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
#include<iostream>
#include<set>
#include<string>
class Cat
{
public:
Cat(int age, std::string name)
:mAge(age)
,mName(name)
{}
void speak() const
{
std::cout << mAge << " " << mName << std::endl;
}
int age() const
{
return mAge;
}
const std::string& name() const
{
return mName;
}
private:
int mAge;
std::string mName;
};
bool operator < (const Cat &cat1, const Cat &cat2) //operator 정의
{
return cat1.age() < cat2.age();
}
int main()
{
std::set<Cat> cats;
cats.emplace(1, "kitty");
cats.emplace(2, "nabi");
cats.emplace(2, "meow"); //set의 특징에 의해 set에 들어오지 않음(2 중복)
for (const auto &cat : cats)
{
cat.speak();
}
std::cout << std::endl;
}
#include<iostream>
#include<set>
int main()
{
std::multiset<int> nums{ 1,2,7,7,4,5,5 };
for (const auto& num : nums)
{
std::cout << num << " "; //1 2 4 5 5 7 7 출력
}
std::cout << std::endl;
}
numPairs[1] = 1001;
key 값을 통해 value값을 바꿀 수 있다.numPairs[6];
지정하지 않은 key값인 6에 접근을 하는 경우 원치 않은 동작 발생 #include<iostream>
#include<map>
#include<string>
int main()
{
std::map<int, int> numPairs;
std::map<int, std::string> nameLists;
numPairs.emplace(1, 101);
numPairs.emplace(2, 102);
numPairs.emplace(3, 103);
numPairs.emplace(4, 104);
numPairs.emplace(5, 105);
numPairs.emplace(5, 505); //중복 허용 x
for (const auto &num:numPairs)
{
std::cout << num.first<< " " << num.second << std::endl;
}
//int와 string 짝으로도 사용 가능
nameLists.emplace(1, "cat");
nameLists.emplace(3, "dog");
nameLists.emplace(2, "person");
for (const auto& name : nameLists)
{
std::cout << name.first << ", " << name.second << std::endl;
//1, cat 2, person 3, dog 출력
}
return 0;
}
reserve()
를 통해 미리 공간을 확보해 두는 것이 좋다.max_load_factor()
로 최대 공간을 정해둘 수 있다.#include<iostream>
#include<string>
#include<unordered_set>>
int main()
{
std::unordered_set<std::string> uordSet; //heap 공간에 저장
uordSet.reserve(1000);
uordSet.emplace("abc");
uordSet.emplace("def");
uordSet.emplace("gji");
uordSet.emplace("jkl");
std::cout << "bucket: " << uordSet.bucket_count() << std::endl; // bucket count
std::cout << "abc: " << std::hash<std::string>{}("abc") << "bucket num: " << uordSet.bucket("abc") << std::endl;
std::cout << "def: " << std::hash<std::string>{}("def") << "bucket num: " << uordSet.bucket("def") << std::endl;
std::cout << "gji: " << std::hash<std::string>{}("gji") << "bucket num: " << uordSet.bucket("gji") << std::endl;
std::cout << "jkl: " << std::hash<std::string>{}("jkl") << "bucket num: " << uordSet.bucket("jkl") << std::endl;
uordSet.find("abc");
uordSet.erase("abc");
return 0;
}
#include<iostream>
#include<string>
#include<unordered_set>
//Cat class
class Cat
{
public:
Cat(int age, std::string name)
:mAge(age)
, mName(name)
{}
void speak() const
{
std::cout << mAge << " " << mName << std::endl;
}
int age() const
{
return mAge;
}
const std::string& name() const
{
return mName;
}
private:
int mAge;
std::string mName;
};
//Cat hash
struct CatHash
{
std::size_t operator()(Cat const& c) const noexcept
{
std::size_t h1 = std::hash<int>{}(c.age());
std::size_t h2 = std::hash<std::string>{}(c.name());
return h1 ^ h2;
}
};
//Cat hash namespace version
namespace std
{
template<>
struct hash<Cat>
{
std::size_t operator()(Cat const& c) const noexcept
{
std::size_t h1 = std::hash<int>{}(c.age());
std::size_t h2 = std::hash<std::string>{}(c.name());
return h1 ^ h2;
}
};
}
bool operator ==(const Cat& c1, const Cat& c2) //equality 정의
{
return (c1.age() == c2.age() && c1.name() == c2.name());
}
int main()
{
Cat kitty{ 1,"kitty" };
Cat nabi{ 2,"nabi" };
std::unordered_set<Cat, CatHash>cats;
//std::unordered_multiset<Cat, CatHash>cats; 중복 허용
//std::unordered_set<Cat>cats; //namespace 사용 version
cats.emplace(kitty);
cats.emplace(nabi);
cats.emplace(2, "nabi");
for (const auto& cat : cats)
{
cat.speak();
}
//1 kitty 2 nabi 출력
return 0;
}
#include<iostream>
#include<unordered_map>
#include<string>
int main()
{
std::unordered_map<int, std::string> idNames;
//std::unordered_multimap<int, std::string> idNames; 중복 허용
idNames.emplace(1234, "Leem");
idNames.emplace(1111, "Kim");
idNames.emplace(9999, "Park");
idNames.emplace(1111, "KIMKIM"); //중복 제거
idNames[1111] = "KIM";
for (const auto& name : idNames)
{
std::cout << name.first << " " << name.second << std::endl;
}
}
구성 | 시간 복잡도 | 필요한 operator | sorted여부 | value값 고려 여부 | rehasing 여부 | |
---|---|---|---|---|---|---|
set | tree | O(logN) | comparison | o | x | x |
map | tree | O(logN) | comparison | o | o | x |
unordered_set | hash | O(1) | hash function & equality | x | x | o |
unordered_map | hash | O(1) | hash function & equality | x | o | o |