Detailed explanation of set/multiset container for C + + basic learning

Posted by Flinch on Wed, 26 Jan 2022 21:10:46 +0100

1. Basic concepts of set

Introduction:

  • All elements are automatically sorted on insertion
    Essence:
  • set/multiset is an associative container, and its underlying structure is implemented by binary tree.
    Difference between set and multiset:

  • set does not allow duplicate elements in the container

  • multiset allows duplicate elements in a container

2. set construction and assignment

Function Description: create set container and assign values
Construction:

  • set<T> st; // Default constructor:
  • set(const set &st); // Copy constructor:

Assignment:

  • set& operator=(const set &st); // Overloaded equal sign operator

Code example:

#include <set>

void printSet(set<int> & s)
{
	for (set<int>::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

//Construction and assignment
void test01()
{
	set<int> s1;

	s1.insert(10);
	s1.insert(30);
	s1.insert(20);
	s1.insert(40);
	printSet(s1);

	//copy construction 
	set<int>s2(s1);
	printSet(s2);

	//assignment
	set<int>s3;
	s3 = s2;
	printSet(s3);
}

int main() {

	test01();

	system("pause");

	return 0;
}

Summary:

  • insert is used when inserting data into the set container.
  • The data inserted into the set container will be sorted automatically.

3. set size and swap

Function Description:

  • Count the size of set container and exchange set container

Function prototype:

  • size();` // Returns the number of elements in the container
  • empty(); // Determine whether the container is empty
  • swap(st); // Swap two collection containers

Example:

#include <set>

void printSet(set<int> & s)
{
	for (set<int>::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

//size
void test01()
{

	set<int> s1;
	
	s1.insert(10);
	s1.insert(30);
	s1.insert(20);
	s1.insert(40);

	if (s1.empty())
	{
		cout << "s1 Empty" << endl;
	}
	else
	{
		cout << "s1 Not empty" << endl;
		cout << "s1 The size of the is: " << s1.size() << endl;
	}

}

//exchange
void test02()
{
	set<int> s1;

	s1.insert(10);
	s1.insert(30);
	s1.insert(20);
	s1.insert(40);

	set<int> s2;

	s2.insert(100);
	s2.insert(300);
	s2.insert(200);
	s2.insert(400);

	cout << "Before exchange" << endl;
	printSet(s1);
	printSet(s2);
	cout << endl;

	cout << "After exchange" << endl;
	s1.swap(s2);
	printSet(s1);
	printSet(s2);
}

int main() {

	//test01();

	test02();

	system("pause");

	return 0;
}

Summary:

  • Statistical size - size
  • Judge whether it is empty empty
  • swap container - swap

4. set insert and delete

Function Description:

  • The set container inserts and deletes data

Function prototype:

  • insert(elem); // Inserts an element into the container.
  • clear(); // Clear all elements
  • erase(pos); // Delete the element referred to by the POS iterator and return the iterator of the next element.
  • erase(beg,end); // Delete all elements of the interval [beg, end], and return the iterator of the next element.
  • erase(elem); // Delete the element with element in the container.

Example:

#include <set>

void printSet(set<int> & s)
{
	for (set<int>::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

//Insert and delete
void test01()
{
	set<int> s1;
	//insert
	s1.insert(10);
	s1.insert(30);
	s1.insert(20);
	s1.insert(40);
	printSet(s1);

	//delete
	s1.erase(s1.begin());
	printSet(s1);

	s1.erase(30);
	printSet(s1);

	//empty
	//s1.erase(s1.begin(), s1.end());
	s1.clear();
	printSet(s1);
}

int main() {

	test01();

	system("pause");

	return 0;
}

Summary:

  • Insert - insert
  • Delete erase
  • Empty - clear

5. set lookup and statistics

Function Description:

  • Search data and statistics for the set container

Function prototype:

  • find(key); // Find out whether the key exists. If so, return the iterator of the element of the key; If it does not exist, return set end();
  • count(key); // Count the number of key elements
    Example:
#include <set>

//Search and statistics
void test01()
{
	set<int> s1;
	//insert
	s1.insert(10);
	s1.insert(30);
	s1.insert(20);
	s1.insert(40);
	
	//lookup
	set<int>::iterator pos = s1.find(30);

	if (pos != s1.end())
	{
		cout << "Found element: " << *pos << endl;
	}
	else
	{
		cout << "Element not found" << endl;
	}

	//Statistics
	int num = s1.count(30);
	cout << "num = " << num << endl;
}

int main() {

	test01();

	system("pause");

	return 0;
}

Summary:

  • Find - find (the iterator is returned)
  • Statistics - count (for set, the result is 0 or 1)

6. Difference between set and multiset

Learning objectives:

  • Master the difference between set and multiset

difference:

  • set cannot insert duplicate data, while multiset can
  • set will return the insertion result when inserting data, indicating whether the insertion is successful
  • multiset does not detect data, so duplicate data can be inserted
    Example:
#include <set>

//Difference between set and multiset
void test01()
{
	set<int> s;
	pair<set<int>::iterator, bool>  ret = s.insert(10);
	if (ret.second) {
		cout << "First insertion successful!" << endl;
	}
	else {
		cout << "The first insertion failed!" << endl;
	}

	ret = s.insert(10);
	if (ret.second) {
		cout << "The second insertion succeeded!" << endl;
	}
	else {
		cout << "The second insertion failed!" << endl;
	}
    
	//multiset
	multiset<int> ms;
	ms.insert(10);
	ms.insert(10);

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

int main() {

	test01();

	system("pause");

	return 0;
}

Summary:

  • If duplicate data insertion is not allowed, set can be used
  • If you need to insert duplicate data, use multiset

7. pair group creation

Function Description:

  • For paired data, two data can be returned by using the pair group

There are two creation methods:

  • pair<type, type> p = make_pair( value1, value2 );
  • pair<type, type> p ( value1, value2 );

Example:

#include <string>

//Create for group
void test01()
{
	pair<string, int> p(string("Tom"), 20);
	cout << "full name: " <<  p.first << " Age: " << p.second << endl;

	pair<string, int> p2 = make_pair("Jerry", 10);
	cout << "full name: " << p2.first << " Age: " << p2.second << endl;
}

int main() {

	test01();

	system("pause");

	return 0;
}

Summary:

You can create pair groups in both ways. Just remember one

8. set container sorting

Learning objectives:

  • The default sorting rule of set container is from small to large. Master how to change the sorting rule
    Main technical points:
  • Using the imitation function, the sorting rules can be changed

Example 1: set stores built-in data types

#include <set>

class MyCompare 
{
public:
	bool operator()(int v1, int v2) {
		return v1 > v2;
	}
};
void test01() 
{    
	set<int> s1;
	s1.insert(10);
	s1.insert(40);
	s1.insert(20);
	s1.insert(30);
	s1.insert(50);

	//Default from small to large
	for (set<int>::iterator it = s1.begin(); it != s1.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;

	//Specify collation
	set<int,MyCompare> s2;
	s2.insert(10);
	s2.insert(40);
	s2.insert(20);
	s2.insert(30);
	s2.insert(50);

	for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

int main() {

	test01();

	system("pause");

	return 0;
}

Summary: the sorting rules of the set container can be specified by using the imitation function

Example 2: storing user-defined data types

#include <set>
#include <string>

class Person
{
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

	string m_Name;
	int m_Age;

};
class comparePerson
{
public:
	bool operator()(const Person& p1, const Person &p2)
	{
		//Sort by age, descending
		return p1.m_Age > p2.m_Age;
	}
};

void test01()
{
	set<Person, comparePerson> s;

	Person p1("Liu Bei", 23);
	Person p2("Guan Yu", 27);
	Person p3("Fei Zhang", 25);
	Person p4("Zhao Yun", 21);

	s.insert(p1);
	s.insert(p2);
	s.insert(p3);
	s.insert(p4);

	for (set<Person, comparePerson>::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << "full name: " << it->m_Name << " Age: " << it->m_Age << endl;
	}
}
int main() {

	test01();

	system("pause");

	return 0;
}

Summary:

For custom data types, set must specify a collation before inserting data

Topics: C++ Container