set与map容器

set与map的异同:

        set和map都是根据二叉树来构造的,会将插入的数据自动排序,属于关联式容器,即存储数据的键值对,其中set只存储一个元素,但它的键就是值。都通过键来查找值。

set容器:

        概述:

        set容器中存放的元素会被自动排序,set不允许插入重复值,但multiset允许。set和multiset都在头文件<set>中。

输出set容器中的元素的函数print_st;

template<class T>

void print_st(set<T> st) {
    for (auto it = st.begin(); it != st.end(); it++) {
        cout << *it << "  ";
    }
    cout << endl;
}

        构造set容器:

        set<参数类型> 容器名; 如set<int> st;。还有set<int> st(const set<int> &st1);拷贝构造。

	set<int> st;
	st.insert(2);
	print_st(st);

	set<int> st1(st);
	print_st(st1);

             查看容器大小:

        size,查看容器的大小,即元素个数。empty,查看容器是否为空。

	set<int> st;
	st.insert(2);
	print_st(st);

	if (st.empty()) {
		cout << "容器为空" << endl;
	}
	else {
		cout << "容器的大小为:" << st.size() << endl;
	}

        容器的插入与删除:

        insert和emplace都是插入函数,insert(int elem);将元素elem插入容器中,返回一个pair<iterator, bool>类型的数据,该数据的第一个参数是.first,表示指向插入位置的迭代器;第二个参数是.second,表示是否插入成功。insert(起始迭代器 start,终止迭代器 end);将起始迭代器与终止迭代器中的数据插入容器中。emplace用法与insert相似,emplace(构造元素所需参数);也会返回一个pair<iterator, bool>类型的数据,用法与insert相同。emplace在插入元素时不会构造临时变量。

	set<int> st;
	st.insert(2);
	print_st(st);

	auto it = st.insert(7);
	cout << "插入的数据为:" << *it.first << "  是否成功插入:" << it.second << endl;
	print_st(st);   
	auto it = st.insert(7);   //再次插入7,会发现it.second是0,而且输出只有一个7.
	cout << "插入的数据为:" << *it.first << "  是否成功插入:" << it.second << endl;

	//使用emplace插入
	st.emplace(4);
	print_st(st);//先插入7,再插入4,但输出顺序是 2 4 7。

	set<int> st1;
	st1.insert(st.begin(), st.end());
	print_st(st1);

	//这个没啥子用,因为你插入后还会再排序,了解一下即可
	st.insert(st.begin(), 3);
	print_st(st);

        erase是常用的删除函数,erase(迭代器 pos);表示删除迭代器所指向的元素,返回指向下一个元素的迭代器。erase(起始迭代器start, 终止迭代器end);删除起始迭代器与终止迭代器之间的数据,返回指向下一个元素的迭代器。erase(int elem);删除键为elem的数据,返回删除的元素个数。clear();清楚容器中的所有元素。

	set<int> st;
	st.insert(2);
	st.insert(3);
	st.insert(5);
	st.insert(4);
	print_st(st);

	auto it = st.erase(st.begin());
	cout << *it << endl;
	print_st(st);

	auto it1 = st.erase(4);  //删除键(值)为4的元素
	cout << it1 << endl;
	print_st(st);

	st.erase(st.begin(), st.end());

	st.clear();

        容器的查找与统计:

        容器的查找与统计都是根据键值进行的。find(int key);用于查找键为key的元素,若找到,返回指向该元素的迭代器;否则返回终止迭代器st.end()。count(int key);用于统计键为key的元素数目。

	set<int> st;
	st.insert(2);
	st.insert(3);
	st.insert(5);
	st.insert(4);
	print_st(st);

	auto it = st.find(3);
	if (it == st.end()) {
		cout << "未找到该键值" << endl;
	}
	else {
		cout << "键值为:" << *it << endl;
	}

	cout << "容器中3的个数为:" << st.count(3) << endl;

        set与multiset:

        set不能存储重复的数据,而multiset可以,究其原因是因为multiset在插入时不会检测是否已经插入数据,而是只返回插入位置的迭代器。除此之外用法与set基本相同

	set<int> st;
	auto it1 = st.insert(2);
	cout << *(it1.first) << " " << it1.second << endl;

	multiset<int> mtst;
	auto it = mtst.insert(3);
	cout << *it << endl;

        set容器存储自定义数据类型:

        存储自定义数据类型时要记得编写一个仿函数,在其中重载小括号(),便于set容器排序。

//自定义数据类型
class T1 {
public:
	T1(int a, string n){
		this->age = a;
		this->name = n;
	}
	int age = 0;
	string name;

};
//编写仿函数
class compare1 {
public:
	//按年龄的降序排列,加const表示可以被const类对象调用(记得加const哦)
	bool operator()(const T1 &v1, const T1 &v2) const{
		return v1.age > v2.age;
	}
};

int main() {

	set<T1, compare1> st;
	st.emplace(6, "小红");
	st.emplace(5, "小黄");
	st.emplace(7, "小红");
	st.emplace(7, "小蓝"); //由于用age做排序,所以set容器中age不能重复,但name可以


	for (auto it = st.begin(); it != st.end(); it++) {
		cout << "姓名为:" << it->name << "  年龄为:" << it->age << endl;
	}

	return 0;
}

map容器:

        概述:

        map容器在头文件<map>中,其中存放的是一个键值对pair<数据类型 数据名,数据类型 数据名>;如pair<int age, string name>;在排序与寻找时都是依靠键值操作的。map不允许插入同一个键值,multimap允许。

输出map容器中的数据的函数 print_m

template<class T1, class T2>
void print_m(map<T1, T2> m) {
    for (auto it = m.begin(); it != m.end(); it++) {
        cout << "键为:" << it->first << " 值为:" << it->second << endl;

    }
}

        构建与初始化:

	map<int, int> m;
	m.insert(make_pair(1, 2));
	m.insert(make_pair(1, 3)); //键相同,不允许插入
	m.insert(make_pair(2, 2)); //值相同,但键不同,允许插入
	print_m(m);
//拷贝构造
	map<int, int> m1(m);

        查看容器大小:

        用size函数查看容器大小,即已存储的元素数量。用empty查看容器是否为空。

	map<int, int> m;
	m.insert(make_pair(1, 2));
	m.insert(make_pair(1, 3)); //键相同,不允许插入
	m.insert(make_pair(2, 2)); //值相同,但键不同,允许插入
	print_m(m);
	if (m.empty()) {
		cout << "容器为空" << endl;
	}
	else {
		cout << "容器大小为:" << m.size() << endl;
	}

        插入与删除数据:

        插入数据:insert、emplace。insert(pair<键的类型,值的类型>(键,值));insert(make_pair(键,值));emplace(键,值);这三种作用相同,都是将键值对插入容器中,还会返回一个<iterator, bool>,第一参数是插入的迭代器,第二个参数表示插入是否成功。还有insert(起始迭代器 start,终止迭代器 end);将起始迭代器到终止迭代器之间的数据复制到容器中。

	map<int, int> m;

	m.insert(pair<int, int>(2, 5));

	m.insert(make_pair(1, 2));

	m.emplace(3, 6);
	print_m(m);
	cout << endl;

	map<int, int> m1;
	m1.emplace(4, 6);
	m1.emplace(6, 6);
	m.insert(m1.begin(), m1.end());
	print_m(m);

        删除数据:erase、clear。erase(键);删除容器中对应的键值对。erase(迭代器 pos);清除迭代器指向的数据。erase(起始迭代器 start, 终止迭代器end);清除起始迭代器到终止迭代器之间的数据。clear();清除容器中的数据。

	map<int, int> m;

	m.insert(pair<int, int>(2, 5));

	m.insert(make_pair(1, 2));

	m.emplace(3, 6);
	print_m(m);
	cout << endl;

	m.erase(3);
	print_m(m);
	cout << endl;

	m.erase(m.begin());
	print_m(m);
	cout << endl;

	m.erase(m.begin(), m.end());

	m.clear();

        查找容器中的元素以及个数:

        find(key);通过键来查找值,若找到键,则返回指向该键值对的迭代器,否则返回终止迭代器m.end()。count(key),查找键为key的值的个数。

	map<int, int> m;
	m.insert(pair<int, int>(2, 5));
	m.insert(make_pair(1, 2));
	m.emplace(3, 6);
	print_m(m);

	auto it = m.find(3);
	if (it == m.end()) {
		cout << "未找到键为3" << endl;
	}
	else{
		cout << "键为3对应的值有" << m.count(3) << "个" << endl;
		cout << "键为"<< it->first << "对应的值为:" << it->second << endl;
	}

        map容器存储自定义数据类型:

//自定义数据类型
class T1 {
public:
	T1(int a, string n) {
		this->age = a;
		this->name = n;
	}
	int age = 0;
	string name;

};
//编写仿函数
class compare1 {
public:
	//按年龄的降序排列,加const表示可以被const类对象调用(记得加const哦)
	bool operator()(const T1& v1, const T1& v2) const {
		return v1.age > v2.age;
	}
};

int main() {

	map<T1, int, compare1> st;
	T1 t(2, "小黄");
	st.emplace(t, 3);
	//st.emplace(7, "小蓝", 9); //不能直接这样构建。

	for (auto it = st.begin(); it != st.end(); it++) {
		cout << "姓名为:" << it->first.name << "  年龄为:" << it->first.age << "  值为:" << it->second <<endl;
	}

	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值