370 lines
8.6 KiB
C++
370 lines
8.6 KiB
C++
#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;
|
||
} |