Set_Map/Linux/Main.cc

370 lines
9.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}
int main()
{
// test_set();
// test_map1();
// test_map2();
// test_map3();
// test_multi();
test_Set();
test_Map1();
test_Map2();
return 0;
}