Associative container of c++STL

Table of contents

set container

default constructor of set

set insertion and iterators

Sort the elements of the set collection

Initialization and traversal of the set collection

from small to large (by default)

 from big to small

functor 

set lookup

use of pairs

multiset container 

map and multimap containers 

Map insertion and iterators

map size

map deletion

map lookup


Associative containers (Associated containers), the element position depends on a specific sorting criterion, and has nothing to do with the insertion order

In c++STL there are mainly set, multiset, map, multimap

set container

  • set is a collection container, the elements contained in it are unique, and the elements in the collection are arranged in a certain order. The element insertion process is inserted according to the sorting rules, so the insertion position cannot be specified.
  • The set is implemented using the data structure of the red-black tree variant, which belongs to the balanced binary tree. Faster than vector for insertion and deletion.
  • set cannot directly access elements. (The at.(pos) and [] operators cannot be used).

default constructor of set

set<int> setInt; //A set container for storing int.

set<float> setFloat; //A set container for storing float.

set<string> setString; //A set container to store string.

multiset<int> mulsetInt; //A multi set container storing int.

multi set<float> multisetFloat; //A multi set container storing float.

multi set<string> multisetString; //A multi set container storing string.

set insertion and iterators

  • set.insert(elem); //Insert an element in the container.
  • set.begin(); //Returns the iterator of the first data in the container.
  • set.end(); //Returns the iterator after the last data in the container.
  • set.rbegin(); //Returns an iterator to the last element in the container.
  • set.rend(); //Returns the iterator behind the last last element in the container.

Sort the elements of the set collection

  • set<int,less<int> > setIntA; //The container arranges elements in ascending order.
  • set<int,greater<int>> setIntB; //The container arranges elements in descending order.
  • set<int> is equivalent to set<int,less<int>>.
  • The int in less<int> and greater<int> can be changed to other types, and the type should be consistent with the data type contained in the set.

Initialization and traversal of the set collection

from small to large (by default)

//集合 元素唯一 自动排序 不能按照[]方式插入元素
//默认情况下是从小到大
void main91()
{
	set<int> set1;
	for (int i = 0; i < 5; i++)
	{
		int tmp = rand();
		set1.insert(tmp);
	}
	set1.insert(100);
	set1.insert(100);
	set1.insert(100);
	for (set<int>::iterator it = set1.begin(); it != set1.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
	while (!set1.empty())
	{
		set<int>::iterator it = set1.begin();
		cout << *it << " ";
		set1.erase(set1.begin());
	}
}

 from big to small

void main92()
{
	set<int,greater<int>> set1;
	for (int i = 0; i < 5; i++)
	{
		int tmp = rand();
		set1.insert(tmp);
	}
	set1.insert(100);
	set1.insert(100);
	set1.insert(100);
	for (set<int,greater<int>>::iterator it = set1.begin(); it != set1.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;

}

functor 

For complex data type set collections are sorted by user definition, the mechanism of functor is mainly used.

//仿函数
struct FuncStudent
{
	bool operator()(const Student& left, const Student& right) const
	{
		if (left.m_age < right.m_age)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
};

void main93()
{
	set<Student, FuncStudent> set1;
	Student s1("s1", 32);
	Student s2("s2", 22);
	Student s3("s3", 16);
	Student s4("s4", 55);
	Student s5("s5", 32);

	set1.insert(s1);
	set1.insert(s2);
	set1.insert(s3);
	set1.insert(s4);
	set1.insert(s5);//两个一样的值
	//如何知道插入的结果

	//遍历
	for (set<Student, FuncStudent>::iterator it = set1.begin(); it != set1.end(); it++)
	{
		cout << it->m_age << "\t" << it->m_name << endl;
	}
}

set lookup

  • set.find(elem); //Find the elem element and return an iterator pointing to the elem element.
  • set.count(elem); //Returns the number of elements whose value is elem in the container. For set, either 0 or 1. For multiset, the value may be greater than 1.
  • set.lower_bound(elem); //Returns the iterator of the first >=elem element.
  • set.upper_bound(elem); // Returns an iterator to the first >elem element.
  • set.equal_range(elem); //Returns two iterators of the upper and lower limits equal to elem in the container. The upper limit is a closed interval, and the lower limit is an open interval, such as [beg,end).

use of pairs

  • pair is translated into a pair, and two values ​​​​can be regarded as a unit.
  • The types of the two values ​​stored in pair<T1, T2> can be different, for example, T1 is int and T2 is float. T1, T2 can also be a custom type.
  • pair.first is the first value in the pair, which is of type T1.
  • pair.second is the second value in the pair, which is of type T2.

set<int> setInt;

... // Insert elements 1, 3, 5, 7, 9 into the setInt container

pair< set<int>::iterator , set<int>::iterator > pairIt = setInt.equal_range(5);

set<int>::iterator itBeg = pairIt.first;

set<int>::iterator itEnd = pairIt.second;

//At this time *itBeg==5 and *itEnd == 7

//如何判断insert的返回值
void main94()
{
	set<Student, FuncStudent> set1;
	Student s1("s1", 32);
	Student s2("s2", 22);
	Student s3("s3", 16);
	Student s4("s4", 55);
	Student s5("s5", 32);

	pair<set<Student, FuncStudent>::iterator, bool> pair1;
	pair1 = set1.insert(s1);
	if (pair1.second)
	{
		cout << "插入s1成功" << endl;
	}
	else
	{
		cout << "插入s1失败" << endl;
	}
	set1.insert(s2);
	set1.insert(s3);
	set1.insert(s4);
	pair1 = set1.insert(s5);//两个一样的值
	if (pair1.second)
	{
		cout << "插入s5成功" << endl;
	}
	else
	{
		cout << "插入s5失败" << endl;
	}
		//遍历
	for (set<Student, FuncStudent>::iterator it = set1.begin(); it != set1.end(); it++)
	{
		cout << it->m_age << "\t" << it->m_name << endl;
	}
}

multiset container 

  • The difference between multiset and set: set supports unique key values, and each element value can only appear once; while the same value in multiset can appear multiple times.
  • It is not possible to directly modify the element values ​​in the set or multiset container, because this type of container is automatically sorted. If you want to modify the value of an element, you must first delete the original element, and then insert a new element.
void main101()
{
	multiset<int> set1;
	int tmp;

	cout << "请输入multiset集合的值:";
	scanf("%d", &tmp);
	while (tmp != 0)
	{
		set1.insert(tmp);
		cout << "请输入multiset集合的值:";
		scanf("%d", &tmp);
	}

	//遍历
	for (multiset<int>::iterator it = set1.begin(); it != set1.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;

	while (!set1.empty())
	{
		multiset<int>::iterator it = set1.begin();
		cout << *it << " ";
		set1.erase(set1.begin());
	}
}

map and multimap containers 

  • A map is a standard associative container, and a map is a sequence of key-value pairs, that is, (key, value) pairs. It provides fast key-based retrieval capabilities.
  • The key value in the map is unique. The elements in a collection are arranged in a certain order. The element insertion process is inserted according to the sorting rules, so the insertion position cannot be specified.
  • The specific implementation of map adopts the data structure of a balanced binary tree variant of the red-black tree. Faster than vector for insertion and deletion.
  • The map can directly access the value corresponding to the key, and supports the [] operator, such as map[key]=value.
  • The difference between multimap and map: map supports unique key values, and each key can only appear once; while the same key in multimap can appear multiple times. multimap does not support the [] operator.

Map insertion and iterators

  • map.insert(...); //Insert elements into the container and return pair<iterator,bool>
  • There are three ways to insert elements in the map:

Suppose map<int, string> mapStu;

  • 1. Insert objects by pair

mapStu.insert( pair<int,string>(3,"Xiao Zhang") );

  • 2. Insert objects by pair

mapStu.inset(make_pair(-1, "Principal-1"));

  • 3. Insert objects by value_type

mapStu.insert(  map<int,string>::value_type(1,"小李")  );

  • 4. Insert values ​​​​through the array

mapStu[3] = "Xiao Liu";

mapStu[5] = "Xiao Wang";

  • The first three methods use the insert() method, and the return value of this method is pair<iterator, bool>
  • The fourth method is very intuitive, but there is a performance problem. When inserting 3, first search for the item whose primary key is 3 in mapStu, if not found, insert a pair whose key is 3 and value is the initialization value into mapStu, and then modify the value to "Xiao Liu". If it is found that the key 3 already exists, modify the value corresponding to this key.
  • string strName = mapStu[2]; // fetch operation or insert operation
  • Only when the key 2 exists in mapStu is the correct fetch operation, otherwise an instance will be automatically inserted, the key is 2, and the value is the initialization value.

map size

  • map.size(); //returns the number of elements in the container
  • map.empty();//Determine whether the container is empty

map deletion

  • map.clear(); //Delete all elements
  • map.erase(pos); //Delete the element pointed by the pos iterator and return the iterator of the next element.
  • map.erase(beg,end); //Delete all elements in the interval [beg,end), and return the iterator of the next element.
  • map.erase(keyElem); //Delete the pair whose key is keyElem in the container.

map lookup

  • map.find(key); Find whether the key key exists, if it exists, return the iterator of the element of the key; if it does not exist, return map.end();
  • map.count(keyElem); //Returns the number of pairs whose key is keyElem in the container. For map, it is either 0 or 1. For multimap, the value may be greater than 1.
//map的添加/遍历/删除
void main111()
{
	map<int, string> map1;
	
	//方法一
	map1.insert(pair<int, string>(1, "teacher01"));
	map1.insert(pair<int, string>(2, "teacher02"));
	
	//方法二
	map1.insert(make_pair(3, "teacher03"));
	map1.insert(make_pair(4, "teacher04"));

	//方法三
	map1.insert(map<int, string>::value_type(5, "teacher05"));
	map1.insert(map<int, string>::value_type(6, "teacher06"));
	
	//方法四
	map1[7] = "teacher07";
	map1[8] = "teacher08";

	//容器的遍历
	for (map<int, string>::iterator it = map1.begin(); it != map1.end(); it++)
	{
		cout << it->first << "\t" << it->second << endl;
	}
	cout << "遍历结束" << endl;

	//容器的删除
	while (!map1.empty())
	{
		map<int, string>::iterator it = map1.begin();
		cout << it->first << "\t" << it->second << endl;
		map1.erase(it);
	}
}

//插入的四种方法异同
//前三种返回值是pair<iterator,bool>
//前三种方法若key已经存在则报错
//方法四    若key已经存在则覆盖
void main112()
{
	map<int, string> map1;

	//方法一
	pair<map<int, string>::iterator,bool> mypair1 = map1.insert(pair<int, string>(1, "teacher01"));
	map1.insert(pair<int, string>(2, "teacher02"));

	//方法二
	pair<map<int, string>::iterator, bool> mypair3 = map1.insert(make_pair(3, "teacher03"));
	map1.insert(make_pair(4, "teacher04"));

	//方法三
	pair<map<int, string>::iterator, bool> mypair5 = map1.insert(map<int, string>::value_type(5, "teacher05"));
	if (mypair5.second)
	{
		cout << mypair5.first->first << mypair5.first->second << endl;
	}
	else
	{
		cout << "key5 插入失败" << endl;
	}
	pair<map<int, string>::iterator, bool> mypair6 = map1.insert(map<int, string>::value_type(5, "teacher06"));
	if (mypair6.second)
	{
		cout << mypair6.first->first << mypair6.first->second << endl;
	}
	else
	{
		cout << "key5 插入失败" << endl;
	}
	//方法四
	map1[7] = "teacher07";
	map1[7] = "teacher77";

	//容器的遍历
	for (map<int, string>::iterator it = map1.begin(); it != map1.end(); it++)
	{
		cout << it->first << "\t" << it->second << endl;
	}
	cout << "遍历结束" << endl;
}

 

void main113()
{
	map<int, string> map1;

	//方法一
	map1.insert(pair<int, string>(1, "teacher01"));
	map1.insert(pair<int, string>(2, "teacher02"));

	//方法二
	map1.insert(make_pair(3, "teacher03"));
	map1.insert(make_pair(4, "teacher04"));

	//方法三
	map1.insert(map<int, string>::value_type(5, "teacher05"));
	map1.insert(map<int, string>::value_type(6, "teacher06"));

	//方法四
	map1[7] = "teacher07";
	map1[8] = "teacher08";

	//容器的遍历
	for (map<int, string>::iterator it = map1.begin(); it != map1.end(); it++)
	{
		cout << it->first << "\t" << it->second << endl;
	}
	cout << "遍历结束" << endl;

	//map的查找
	map<int, string>::iterator it2 = map1.find(100);
	if (it2 == map1.end())
	{
		cout << "key 100的值不存在" << endl;
	}
	else
	{
		cout << it2->first << "\t" << it2->second << endl;
	}

	//equal_range
	pair<map<int, string>::iterator, map<int, string>::iterator> mypair = map1.equal_range(5);//返回两个迭代器 形成一个pair
	//第一个迭代器>=5的位置
	//第二个迭代器>5的位置
	if (mypair.first == map1.end())
	{
		cout << "第一个迭代器不存在" << endl;
	}
	else
	{
		cout << mypair.first->first << "\t" << mypair.first->second << endl;
	}

	//使用第二个迭代器
	if (mypair.second == map1.end())
	{
		cout << "第一个迭代器不存在" << endl;
	}
	else
	{
		cout << mypair.second->first << "\t" << mypair.second->second << endl;
	}
}

 

 

Guess you like

Origin blog.csdn.net/qq_45526401/article/details/130185018