Set_Map/Linux/Main.cc

398 lines
9.9 KiB
C++
Raw Permalink Normal View History

#include <iostream>
#include <set>
#include <map>
#include "Set.hpp"
#include "Map.hpp"
using namespace std;
using namespace Lenyiin;
// 序列式容器: vector/list/string/deque/array/forward_list
// 关联式容器: set/multiset/map/multimap/unordered_set/unordered_multiset/unordered_map/unordered_multimap
void test_set()
{
set<int> s1; // set默认排序为从小到大 set底层是搜索树
s1.insert(10);
s1.insert(20);
s1.insert(5);
s1.insert(2);
s1.insert(1);
s1.insert(8);
s1.insert(14);
s1.insert(44);
s1.insert(23);
s1.insert(0);
s1.insert(2);
s1.insert(1);
s1.insert(8);
s1.insert(14);
// 排序 + 去重
set<int>::iterator it = s1.begin();
while (it != s1.end())
{
//*it = 100; // set中的元素是只读的不能修改
cout << *it << " ";
it++;
}
cout << endl;
// 范围for
for (auto e : s1)
{
cout << e << " ";
}
cout << endl;
// 拷贝构造 底层默认是一个深拷贝
set<int> s2(s1);
for (auto e : s2)
{
cout << e << " ";
}
cout << endl;
// 删除
// find()是成员函数只能用于set/multiset/map/multimap
// set<int>::iterator pos = s2.find(5);
auto pos = s2.find(5);
// find()是泛型算法,可以用于所有容器
// s.find() O(logN) s.begin() O(1) s.end() O(1)
// find(s.begin(), s.end(), 5) O(N) 效率会低不少
// auto pos = find(s2.begin(), s2.end(), 5);
if (pos != s2.end())
{
s2.erase(pos);
}
for (auto e : s2)
{
cout << e << " ";
}
cout << endl;
// 或者直接删
s2.erase(8);
s2.erase(80); // 和迭代器的区别在于:删除不存在的元素,不会报错
for (auto e : s2)
{
cout << e << " ";
}
cout << endl;
}
void test_map1()
{
map<int, int> m1;
m1.insert(pair<int, int>(1, 1)); // pair是一个模板类可以用来创建pair对象
m1.insert(pair<int, int>(3, 3));
m1.insert(pair<int, int>(2, 2));
m1.insert(pair<int, int>(5, 5));
m1.insert(pair<int, int>(6, 6));
m1.insert(pair<int, int>(4, 4)); // pair构造函数构造一个匿名对象然后插入到map中
// 日常大家喜欢用make_pair()来构造pair对象因为他不用声明模板参数编译器自动推
m1.insert(make_pair(7, 7)); // 函数模板构造一个pair对象
map<int, int>::iterator it = m1.begin();
while (it != m1.end())
{
// cout << *it << " "; // C++不支持返回两个数
cout << (*it).first << " " << (*it).second << endl; // operator*()返回的是节点中值的引用
cout << it->first << " " << it->second << endl; // operator->()返回的是节点的指针 也就是pair<k, v>的指针
it++;
}
cout << endl;
// 范围for
for (auto &e : m1)
{
cout << e.first << " " << e.second << endl;
}
cout << endl;
}
void test_map2()
{
std::map<std::string, std::string> dirt;
dirt.insert(pair<std::string, std::string>("sort", "排序"));
dirt.insert(make_pair("string", "字符串"));
dirt.insert(make_pair("left", "左边")); // 按照ASCII码排序
std::map<std::string, std::string>::iterator it = dirt.begin();
while (it != dirt.end())
{
cout << it->first << " " << it->second << endl;
it++;
}
cout << endl;
}
void test_map3()
{
// 统计单词出现的次数
string strArr[] = {"西瓜", "苹果", "西瓜", "苹果", "西瓜", "香蕉", "西瓜", "樱桃", "西瓜", "苹果",
"西瓜", "苹果", "西瓜", "香蕉", "西瓜", "樱桃", "西瓜", "苹果", "西瓜", "苹果", "西瓜", "香蕉",
"西瓜", "樱桃", "西瓜", "苹果", "西瓜", "苹果", "西瓜", "香蕉", "西瓜", "樱桃", "西瓜", "苹果",
"西瓜", "苹果", "西瓜", "香蕉", "西瓜", "樱桃", "西瓜", "苹果", "西瓜", "苹果", "西瓜", "香蕉"};
map<string, int> countMap;
// 第一种方法
for (auto &str : strArr)
{
map<string, int>::iterator pos = countMap.find(str);
if (pos != countMap.end())
{
pos->second++;
}
else
{
countMap.insert(make_pair(str, 1));
}
}
for (auto &e : countMap)
{
cout << e.first << " " << e.second << endl;
}
cout << endl;
// 第二种方法
for (auto &str : strArr)
{
pair<map<string, int>::iterator, bool> ret = countMap.insert(make_pair(str, 1));
if (ret.second == false) // 插入失败,说明已经存在
{
ret.first->second++; // 迭代器指向的是插入的元素
}
}
for (auto &e : countMap)
{
cout << e.first << " " << e.second << endl;
}
cout << endl;
// 第三种方法
for (auto &str : strArr)
{
// 1、如果水果不在map中则[]会插入pair<str, 0>, 返回映射对象(次数)的引用进行++
// 2、如果水果在map中则[]会返回水果对应的映射对象(次数)的引用,对它进行++
countMap[str]++;
}
countMap["葡萄"]; // 插入 一般不这么用
countMap["葡萄"] = 100; // 修改
cout << countMap["葡萄"] << endl; // 查找
countMap["哈密瓜"] = 5; // 插入 + 修改
// 一般使用operator[]去
// 1、插入 + 修改
// 2、修改
// 一般不会用他去做查找因为如果key不在会插入数据。
for (auto &e : countMap)
{
cout << e.first << " " << e.second << endl;
}
cout << endl;
}
void test_multi()
{
// multiset根set的区别就是允许键值冗余
multiset<int> s1; // 使用和set一样只是multiset可以存放重复的元素
s1.insert(10);
s1.insert(20);
s1.insert(5);
s1.insert(2);
s1.insert(1);
s1.insert(8);
s1.insert(8);
s1.insert(14);
s1.insert(44);
s1.insert(23);
s1.insert(0);
s1.insert(2);
s1.insert(1);
s1.insert(8);
s1.insert(8);
s1.insert(14);
for (auto e : s1)
{
cout << e << " ";
}
cout << endl;
auto pos = s1.find(8); // 查找到的是重复元素的第一个元素地址
cout << *pos << endl;
pos++;
cout << *pos << endl;
pos++;
cout << *pos << endl;
pos++;
cout << *pos << endl;
pos++;
cout << *pos << endl;
// multimap和map的区别和上面是一样的
multimap<string, int> mm;
mm.insert(make_pair("苹果", 1));
mm.insert(make_pair("苹果", 1));
mm.insert(make_pair("苹果", 3));
mm.insert(make_pair("西瓜", 2));
mm.insert(make_pair("西瓜", 1));
for (auto &e : mm)
{
cout << e.first << " " << e.second << endl;
}
cout << endl;
}
// 自己实现的 Set Map 测试
void test_Set()
{
Set<int> s;
s.Insert(3);
s.Insert(4);
s.Insert(1);
s.Insert(2);
s.Insert(2);
s.Insert(5);
// 迭代器遍历
Set<int>::iterator it = s.begin();
while (it != s.end())
{
cout << *it << " ";
++it;
}
cout << endl;
// 删除
s.Erase(4);
// for
for (const auto &k : s)
{
cout << k << " ";
}
cout << endl;
cout << "IsRBTree? " << (s.IsRBTree() ? "true" : "false") << endl;
}
void test_Map1()
{
// int a[] = {16, 3, 7, 11, 9, 26, 18, 14, 15};
int a[] = {4, 2, 6, 1, 3, 5, 15, 7, 16, 14};
Map<int, int> m;
for (const auto &e : a)
{
m.Insert(make_pair(e, e));
}
// 迭代器遍历
Map<int, int>::iterator it = m.begin();
while (it != m.end())
{
cout << it->first << ":" << it->second << endl;
++it;
}
cout << endl;
// 删除
m.Erase(4);
// 范围for遍历 for_each 底层也是调用的迭代器实现的遍历
for (const auto &kv : m)
{
cout << kv.first << ":" << kv.second << endl;
}
cout << endl;
cout << "IsRBTree? " << (m.IsRBTree() ? "true" : "false") << endl;
}
void test_Map2()
{
// 统计单词出现的次数
string strArr[] = {"西瓜", "苹果", "西瓜", "苹果", "西瓜", "香蕉", "西瓜", "樱桃", "西瓜", "苹果",
"西瓜", "苹果", "西瓜", "香蕉", "西瓜", "樱桃", "西瓜", "苹果", "西瓜", "苹果", "西瓜", "香蕉",
"西瓜", "樱桃", "西瓜", "苹果", "西瓜", "苹果", "西瓜", "香蕉", "西瓜", "樱桃", "西瓜", "苹果",
"西瓜", "苹果", "西瓜", "香蕉", "西瓜", "樱桃", "西瓜", "苹果", "西瓜", "苹果", "西瓜", "香蕉"};
Map<string, int> countMap;
for (auto &str : strArr)
{
countMap[str]++;
}
// 迭代器遍历
Map<string, int>::iterator it = countMap.begin();
while (it != countMap.end())
{
cout << it->first << ":" << it->second << endl;
++it;
}
cout << endl;
// 删除
countMap.Erase("苹果");
for (const auto &kv : countMap)
{
cout << kv.first << ":" << kv.second << endl;
}
cout << endl;
cout << "IsRBTree? " << (countMap.IsRBTree() ? "true" : "false") << endl;
}
void test_Map3()
{
Lenyiin::Map<int, std::string> map;
// 插入键值对
map.Insert(std::make_pair(1, "one"));
map.Insert(std::make_pair(2, "two"));
map.Insert(std::make_pair(3, "three"));
// 通过 operator[] 访问或插入
map[4] = "four";
std::cout << "Key 4: " << map[4] << std::endl;
// 查找元素
auto it = map.Find(2);
if (it != map.end())
{
std::cout << "Found: " << it->first << " -> " << it->second << std::endl;
}
// 删除元素
map.Erase(1);
// 验证红黑树
cout << "IsRBTree? " << (map.IsRBTree() ? "true" : "false") << endl;
}
int main()
{
// test_set();
// test_map1();
// test_map2();
// test_map3();
// test_multi();
test_Set();
test_Map1();
test_Map2();
test_Map3();
return 0;
}