第 16.6 節

set / map container

0瀏覽次數0訪問次數--跳出率--平均停留

set/multiset containers

Set Basic Concepts

A set is a well-defined collection of distinct objects, called the elements or members of the set. Sets are typically denoted by uppercase letters (e.g., A, B, C), and their elements are enclosed in curly braces. For example:

  • A = {1, 2, 3} is a set containing the numbers 1, 2, and 3.
  • B = {"apple", "banana", "cherry"} is a set of strings.

Key properties:

  1. Uniqueness: Each element in a set is unique (no duplicates).
  2. Unordered: The arrangement of elements does not matter (e.g., {1, 2, 3} = {3, 1, 2}).

Common notation:

  • Element of: x ∈ A means "x is an element of set A."
  • Empty set: ∅ or {} represents a set with no elements.
  • Subset: A ⊆ B means "A is a subset of B" (all elements of A are in B).

Sets are fundamental in mathematics and computer science for grouping and organizing data.

Introduction:

  • All elements will be automatically sorted upon insertion.

Essence:

  • Sets and multisets are associative containers, implemented using binary trees as their underlying structure.

Difference between set and multiset:

  • set: Stores unique elements; each value appears only once.
  • multiset: Allows duplicate elements; the same value can appear multiple times.

Example: In a set, inserting "apple", "banana", "apple" results in {"apple", "banana"}. In a multiset, the same insertion yields {"apple", "apple", "banana"}.

  • Sets do not allow duplicate elements in a container.
  • A multiset permits duplicate elements in the container.

Set construction and assignment

Functional Description: Creating a set container and assigning values to it.

Structure:

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

Assignment:

  • set& operator=(const set &st); //overloading the equality operator

Example:

#include <set>

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

//构造和赋值
void test01()
{
    set<int> s1;

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

    //拷贝构造
    set<int>s2(s1);
    printSet(s2);

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

int main() {

    test01();


    return 0;
}

Running/Observation Results: After running, the corresponding content will be printed according to the output statements. The variable values can be inferred based on the order of initialization, assignment, and function calls.

Summary:

  • When adding data to a set container, use the insert method.
  • The data inserted into a set container is automatically sorted.

set size and swap

Description:

  • Counting the size of set containers and swapping set containers.

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;
}

//大小
void test01()
{

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

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

}

//交换
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 << "交换前" << endl;
    printSet(s1);
    printSet(s2);
    cout << endl;

    cout << "交换后" << endl;
    s1.swap(s2);
    printSet(s1);
    printSet(s2);
}

int main() {

    //test01();

    test02();


    return 0;
}

Running/Observation Results: After running, the corresponding content will be printed according to the output statements. The variable values can be inferred based on the order of initialization, assignment, and function calls.

Summary:

  • size
  • Check if empty --- empty
  • Exchange Container --- swap

Insertion and deletion in a set.

Description:

  • Set container for inserting and deleting data

In C++, std::set is an associative container that stores unique elements in a specific order (typically implemented as a balanced binary search tree). Here’s how to perform insertions and deletions:

Insertion

  1. insert: Adds an element if it’s not already present.
    std::set<int> mySet;
    mySet.insert(10);          // Inserts 10
    mySet.insert(20);          // Inserts 20
    mySet.insert(10);          // Duplicate, no effect
    
  2. emplace: Constructs the element in-place (useful for complex objects).
    mySet.emplace(30);         // Inserts 30
    
  3. Insert range (from another container):
    std::set<int> anotherSet = {40, 50};
    mySet.insert(anotherSet.begin(), anotherSet.end());
    

Return value: insert returns a pair where:

  • first: iterator to the inserted element (or existing element if duplicate).
  • second: true if insertion took place, false otherwise.

Deletion

  1. erase by key (removes all elements matching the key):
    mySet.erase(10);           // Removes the element with value 10
    
  2. erase by iterator (removes a specific element):
    auto it = mySet.find(20);
    if (it != mySet.end()) {
        mySet.erase(it);       // Removes 20
    }
    
  3. erase range:
    mySet.erase(mySet.begin(), mySet.end()); // Clears the set
    
  4. clear: Removes all elements.
    mySet.clear();             // Empties the set
    

Example

#include <iostream>
#include <set>

int main() {
    std::set<int> nums = {1, 2, 3};
    
    nums.insert(4);           // {1, 2, 3, 4}
    nums.erase(2);            // {1, 3, 4}
    
    for (int n : nums) {
        std::cout << n << " ";
    }
    // Output: 1 3 4
    return 0;
}

Complexity

  • Insert/Erase by key: O(log n)
  • Insert/Erase by iterator: Amortized O(1) (but still O(log n) for rebalancing)
  • Search (find): O(log n)

All operations maintain the sorted order of elements. Duplicates are automatically ignored.

Function prototype:

  • insert(elem); //Insert an element into the container.
  • clear(); // Clear all elements
  • erase(pos); //Deletes the element pointed to by the iterator and returns an iterator to the next element.
  • erase(beg, end); //Erases all elements in the range [beg, end), and returns the iterator to the next element.
  • erase(elem); //Delete the element with value elem from 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;
}

//插入和删除
void test01()
{
    set<int> s1;
    //插入
    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    s1.insert(40);
    printSet(s1);

    //删除
    s1.erase(s1.begin());
    printSet(s1);

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

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

int main() {

    test01();


    return 0;
}

Running/Observation Results: After running, the corresponding content will be printed according to the output statements. The variable values can be inferred based on the order of initialization, assignment, and function calls.

Summary:

  • insert
  • erase
  • clear

set lookup and statistics

Description:

  • Performing data search and statistics operations on a set container.

Function prototype:

  • find(key); //Check if the key exists; if present, return the iterator to the element with that key; if not, return set.end().
  • count(key); //Count the number of elements in key

Example:

#include <set>

//查找和统计
void test01()
{
    set<int> s1;
    //插入
    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    s1.insert(40);
    
    //查找
    set<int>::iterator pos = s1.find(30);

    if (pos != s1.end())
    {
        cout << "找到了元素 : " << *pos << endl;
    }
    else
    {
        cout << "未找到元素" << endl;
    }

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

int main() {

    test01();


    return 0;
}

Running/Observation Results: After running, the corresponding content will be printed according to the output statements. The variable values can be inferred based on the order of initialization, assignment, and function calls.

Summary:

  • 查找 --- find (返回的是迭代器)
  • Count --- count (for set operations, the result is either 0 or 1)

Set and multiset are both associative containers in C++ that store elements in a sorted order, but they differ in how they handle duplicate elements:

  • Set: Each element must be unique. If you try to insert a duplicate, the operation is ignored.
  • Multiset: Allows duplicate elements. You can insert multiple identical values.

Example:

  • std::set<int> mySet{1, 2, 3} (inserting another 1 has no effect).
  • std::multiset<int> myMultiSet{1, 1, 2, 3} (all inserts are stored).

Both provide efficient lookup (typically logarithmic time complexity) and maintain elements in sorted order. Use set when uniqueness is required, and multiset when duplicates are allowed.

Learning Objectives:

  • Master the differences between set and multiset.

Difference:

  • Sets do not allow the insertion of duplicate data, whereas multisets do.
  • The SET command does return an insertion result when inserting data, indicating whether the insertion was successful. Specifically, it returns "OK" when the insertion is successful. When using SET with the NX option, if the key already exists, the operation fails and returns nil. Similarly, with the XX option, if the key does not exist, the operation also fails and returns nil.
  • A multiset does not check the data, therefore duplicate data can be inserted.

Example:

#include <set>

//set和multiset区别
void test01()
{
    set<int> s;
    pair<set<int>::iterator, bool>  ret = s.insert(10);
    if (ret.second) {
        cout << "第一次插入成功!" << endl;
    }
    else {
        cout << "第一次插入失败!" << endl;
    }

    ret = s.insert(10);
    if (ret.second) {
        cout << "第二次插入成功!" << endl;
    }
    else {
        cout << "第二次插入失败!" << 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();


    return 0;
}

Running/Observation Results: After running, the corresponding content will be printed according to the output statements. The variable values can be inferred based on the order of initialization, assignment, and function calls.

Summary:

  • If duplicate data insertion is not allowed, you can use a set.
  • If you need to insert duplicate data, you can use a multiset. Unlike a set, a multiset allows duplicate elements and automatically sorts them. Here's how you can use it:

Example Code:

#include <iostream>
#include <set>

int main() {
    std::multiset<int> ms;

    // Insert duplicate elements
    ms.insert(5);
    ms.insert(3);
    ms.insert(5); // Duplicate allowed
    ms.insert(7);
    ms.insert(3); // Another duplicate

    // Display elements
    std::cout << "Elements in multiset: ";
    for (const auto& elem : ms) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // Count occurrences of an element
    std::cout << "Count of 5: " << ms.count(5) << std::endl;

    return 0;
}

Output:

Elements in multiset: 3 3 5 5 7 
Count of 5: 2

Key Features:

  1. Allows Duplicates: Can store multiple identical values.
  2. Automatic Sorting: Elements are sorted in ascending order by default.
  3. Search Operations: Provides efficient find(), count(), and lower_bound()/upper_bound() methods.
  4. Erase Operations: Can erase all instances of a value with erase(value) or a specific iterator.

When to Use:

  • When you need a sorted container that allows duplicates.
  • When you need efficient lookup and iteration over ordered data with duplicates.

Alternatives:

  • Set: If duplicates are not needed.
  • Map: If you need key-value pairs with unique keys.
  • Unordered containers: For faster average-case performance without sorting.

Use multiset when sorted, duplicate-friendly storage is required!

Creating pair groups

Description:

  • When dealing with paired data, tuples can be used to return two data items.

Two creation methods:

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

Example:

#include <string>

//对组创建
void test01()
{
    pair<string, int> p(string("Tom"), 20);
    cout << "姓名: " <<  p.first << " 年龄: " << p.second << endl;

    pair<string, int> p2 = make_pair("Jerry", 10);
    cout << "姓名: " << p2.first << " 年龄: " << p2.second << endl;
}

int main() {

    test01();


    return 0;
}

Running/Observation Results: After running, the corresponding content will be printed according to the output statements. The variable values can be inferred based on the order of initialization, assignment, and function calls.

Summary:

Both methods can be used to create groups; just keep one in mind.

Sorting a set container

In C++, the std::set container is inherently sorted by its key according to the comparison function used. It maintains elements in ascending order by default, so explicit sorting is not required. If you need to change the sorting order, you can provide a custom comparator at the time of declaration.

Learning Objectives:

  • The default sorting rule for set containers is in ascending order; learn how to change the sorting rule.

主要技术点:

  • By using functors, you can change the sorting rules.

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);

    //默认从小到大
    for (set<int>::iterator it = s1.begin(); it != s1.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;

    //指定排序规则
    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();


    return 0;
}

Running/Observation Results: After running, the corresponding content will be printed according to the output statements. The variable values can be inferred based on the order of initialization, assignment, and function calls.

In summary: functors can be used to specify the sorting rules for a set container.

Example 2 using a set to store custom 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)
    {
        //按照年龄进行排序  降序
        return p1.m_Age > p2.m_Age;
    }
};

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

    Person p1("刘备", 23);
    Person p2("关羽", 27);
    Person p3("张飞", 25);
    Person p4("赵云", 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 << "姓名: " << it->m_Name << " 年龄: " << it->m_Age << endl;
    }
}
int main() {

    test01();


    return 0;
}

Running/Observing the results: After running, the example will print variable values or addresses; address values depend on the runtime environment, so focus on observing the relative positioning and pointer changes of similar objects.

Summary:

For custom data types, a set must specify a sorting rule before data can be inserted.

map/multimap containers

map基本概念

In robotics, a map is a representation of the environment that a robot uses to understand its surroundings and navigate. It is typically created using data from sensors like LiDAR, cameras, or ultrasonic sensors. Maps can be represented in various ways, such as occupancy grids, which divide the space into cells and mark them as occupied, free, or unknown, or topological maps, which focus on connectivity between key points. A good map is essential for localization, path planning, and obstacle avoidance. In the context of a Robot Operating System, maps are often generated and managed as part of the robot's environmental setup for autonomous operation.

Introduction:

  • map中所有元素都是pair。
  • The first element in a pair serves as the key for indexing, while the second element is the actual value.
  • All elements will automatically sort by their key values.

Essence:

  • Map and multimap are associative containers implemented using binary tree structures.

Pros:

  • Based on the key value, you can quickly find the corresponding value.

Difference between map and multimap: Both are associative containers in C++ that store key-value pairs, typically implemented as balanced binary trees (like red-black trees). The primary distinction is that map enforces unique keys, while multimap allows duplicate keys. Consequently, map::operator[] provides direct access to a key's value, whereas in multimap, keys with duplicates must be accessed via iterators (e.g., equal_range or lower_bound).

  • Map does not allow duplicate key elements in the container.
  • Multimap allows duplicate key values for elements in the container.

Map construction and assignment.

Description:

  • Construction and assignment operations on the map container.

Function prototype:

Construction:

  • map<T1, T2> mp; //map default constructor:
  • map(const map &mp); //copy constructor

Assignment:

  • map& operator=(const map &mp); //overloading the equality operator

Example:

#include <map>

void printMap(map<int,int>&m)
{
    for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
    {
        cout << "key = " << it->first << " value = " << it->second << endl;
    }
    cout << endl;
}

void test01()
{
    map<int,int>m; //默认构造
    m.insert(pair<int, int>(1, 10));
    m.insert(pair<int, int>(2, 20));
    m.insert(pair<int, int>(3, 30));
    printMap(m);

    map<int, int>m2(m); //拷贝构造
    printMap(m2);

    map<int, int>m3;
    m3 = m2; //赋值
    printMap(m3);
}

int main() {

    test01();


    return 0;
}

Running/Observing the results: After running, the example will print variable values or addresses; address values depend on the runtime environment, so focus on observing the relative positioning and pointer changes of similar objects.

Summary: All elements in a map appear in pairs, so you need to use pair groups when inserting data.

Map size and exchange

Description:

  • Counting map container size and swapping map containers.

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 <map>

void printMap(map<int,int>&m)
{
    for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
    {
        cout << "key = " << it->first << " value = " << it->second << endl;
    }
    cout << endl;
}

void test01()
{
    map<int, int>m;
    m.insert(pair<int, int>(1, 10));
    m.insert(pair<int, int>(2, 20));
    m.insert(pair<int, int>(3, 30));

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

//交换
void test02()
{
    map<int, int>m;
    m.insert(pair<int, int>(1, 10));
    m.insert(pair<int, int>(2, 20));
    m.insert(pair<int, int>(3, 30));

    map<int, int>m2;
    m2.insert(pair<int, int>(4, 100));
    m2.insert(pair<int, int>(5, 200));
    m2.insert(pair<int, int>(6, 300));

    cout << "交换前" << endl;
    printMap(m);
    printMap(m2);

    cout << "交换后" << endl;
    m.swap(m2);
    printMap(m);
    printMap(m2);
}

int main() {

    test01();

    test02();


    return 0;
}

Running/Observing the results: After running, the example will print variable values or addresses; address values depend on the runtime environment, so focus on observing the relative positioning and pointer changes of similar objects.

Summary:

  • size
  • Check if empty --- empty
  • Exchange Container --- swap

map insertion and deletion

Description:

  • Insert data and delete data from map container.

Function prototype:

  • insert(elem); //Insert an element into the container.
  • clear(); // Clear all elements
  • erase(pos); //Deletes the element pointed to by the iterator and returns an iterator to the next element.
  • erase(beg, end); //Erases all elements in the range [beg, end), and returns the iterator to the next element.
  • erase(key); //Remove the element with value 'key' from the container.

Example:

#include <map>

void printMap(map<int,int>&m)
{
    for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
    {
        cout << "key = " << it->first << " value = " << it->second << endl;
    }
    cout << endl;
}

void test01()
{
    //插入
    map<int, int> m;
    //第一种插入方式
    m.insert(pair<int, int>(1, 10));
    //第二种插入方式
    m.insert(make_pair(2, 20));
    //第三种插入方式
    m.insert(map<int, int>::value_type(3, 30));
    //第四种插入方式
    m[4] = 40; 
    printMap(m);

    //删除
    m.erase(m.begin());
    printMap(m);

    m.erase(3);
    printMap(m);

    //清空
    m.erase(m.begin(),m.end());
    m.clear();
    printMap(m);
}

int main() {

    test01();


    return 0;
}

Running/Observing the results: After running, the example will print variable values or addresses; address values depend on the runtime environment, so focus on observing the relative positioning and pointer changes of similar objects.

Summary:

  • There are many ways to insert into a map; remembering one is sufficient.
  • insert
  • erase
  • clear

Map lookup and statistics

Description:

  • Conduct data searches and statistics on map containers.

Function prototype:

  • find(key); //Check if the key exists; if present, return the iterator to the element with that key; if not, return set.end().
  • count(key); //Count the number of elements in key

Example:

#include <map>

//查找和统计
void test01()
{
    map<int, int>m; 
    m.insert(pair<int, int>(1, 10));
    m.insert(pair<int, int>(2, 20));
    m.insert(pair<int, int>(3, 30));

    //查找
    map<int, int>::iterator pos = m.find(3);

    if (pos != m.end())
    {
        cout << "找到了元素 key = " << (*pos).first << " value = " << (*pos).second << endl;
    }
    else
    {
        cout << "未找到元素" << endl;
    }

    //统计
    int num = m.count(3);
    cout << "num = " << num << endl;
}

int main() {

    test01();


    return 0;
}

Running/Observation Results: After running, the corresponding content will be printed according to the output statements. The variable values can be inferred based on the order of initialization, assignment, and function calls.

Summary:

  • 查找 --- find (返回的是迭代器)
  • Count --- count (for map, the result is 0 or 1)

Sorting a map container.

Learning Objectives:

  • The default sorting rule for a map container sorts elements in ascending order based on the key value; learn how to change the sorting rule.

Key Technical Points:

  • By using functors, you can change the sorting rules.

Example:

#include <map>

class MyCompare {
public:
    bool operator()(int v1, int v2) {
        return v1 > v2;
    }
};

void test01() 
{
    //默认从小到大排序
    //利用仿函数实现从大到小排序
    map<int, int, MyCompare> m;

    m.insert(make_pair(1, 10));
    m.insert(make_pair(2, 20));
    m.insert(make_pair(3, 30));
    m.insert(make_pair(4, 40));
    m.insert(make_pair(5, 50));

    for (map<int, int, MyCompare>::iterator it = m.begin(); it != m.end(); it++) {
        cout << "key:" << it->first << " value:" << it->second << endl;
    }
}
int main() {

    test01();


    return 0;
}

Running/Observation Results: After running, the corresponding content will be printed according to the output statements. The variable values can be inferred based on the order of initialization, assignment, and function calls.

Summary:

  • Using a functor, the sorting rules for a map container can be specified.
  • For custom data types, the map must specify the sort ordering, just like the set container.

Case Study - Employee Grouping

Case Description

  • The company hired 10 new employees today (ABCDEFGHIJ). Once these 10 employees join the company, they need to be assigned to which department to work in.
  • Employee information includes: Name, Salary composition; Departments are divided into: Planning, Art, R&D
  • | Employee Name | Department | Salary (USD) | |---------------|---------------|--------------| | Alice | Engineering | 75,000 | | Bob | Marketing | 65,000 | | Charlie | Human Resources | 58,000 | | Diana | Finance | 82,000 | | Edward | Operations | 60,000 | | Fiona | Engineering | 70,000 | | George | Sales | 68,000 | | Hannah | Marketing | 63,000 | | Ivan | Engineering | 78,000 | | Julia | Finance | 85,000 |
  • Insert information through multimap with department number as key and employee as value.
  • Display employee information by department

Implementation Steps

  1. Create 10 employees and place them in a vector.
  2. Iterate through the vector container, extract each employee, and randomly group them.
  3. After grouping, use the employee's department ID as the key and the specific employee as the value to insert into a multimap container.
  4. Display employee information by department

Sample code:

#include<iostream>
using namespace std;
#include <vector>
#include <string>
#include <map>
#include <ctime>

/*
- 公司今天招聘了10个员工(ABCDEFGHIJ),10名员工进入公司之后,需要指派员工在那个部门工作
- 员工信息有: 姓名  工资组成;部门分为:策划、美术、研发
- 随机给10名员工分配部门和工资
- 通过multimap进行信息的插入  key(部门编号) value(员工)
- 分部门显示员工信息
*/

#define CEHUA  0
#define MEISHU 1
#define YANFA  2

class Worker
{
public:
    string m_Name;
    int m_Salary;
};

void createWorker(vector<Worker>&v)
{
    string nameSeed = "ABCDEFGHIJ";
    for (int i = 0; i < 10; i++)
    {
        Worker worker;
        worker.m_Name = "员工";
        worker.m_Name += nameSeed[i];

        worker.m_Salary = rand() % 10000 + 10000; // 10000 ~ 19999
        //将员工放入到容器中
        v.push_back(worker);
    }
}

//员工分组
void setGroup(vector<Worker>&v,multimap<int,Worker>&m)
{
    for (vector<Worker>::iterator it = v.begin(); it != v.end(); it++)
    {
        //产生随机部门编号
        int deptId = rand() % 3; // 0 1 2 

        //将员工插入到分组中
        //key部门编号,value具体员工
        m.insert(make_pair(deptId, *it));
    }
}

void showWorkerByGourp(multimap<int,Worker>&m)
{
    // 0  A  B  C   1  D  E   2  F G ...
    cout << "策划部门:" << endl;

    multimap<int,Worker>::iterator pos = m.find(CEHUA);
    int count = m.count(CEHUA); // 统计具体人数
    int index = 0;
    for (; pos != m.end() && index < count; pos++ , index++)
    {
        cout << "姓名: " << pos->second.m_Name << " 工资: " << pos->second.m_Salary << endl;
    }

    cout << "----------------------" << endl;
    cout << "美术部门: " << endl;
    pos = m.find(MEISHU);
    count = m.count(MEISHU); // 统计具体人数
    index = 0;
    for (; pos != m.end() && index < count; pos++, index++)
    {
        cout << "姓名: " << pos->second.m_Name << " 工资: " << pos->second.m_Salary << endl;
    }

    cout << "----------------------" << endl;
    cout << "研发部门: " << endl;
    pos = m.find(YANFA);
    count = m.count(YANFA); // 统计具体人数
    index = 0;
    for (; pos != m.end() && index < count; pos++, index++)
    {
        cout << "姓名: " << pos->second.m_Name << " 工资: " << pos->second.m_Salary << endl;
    }

}

int main() {

    srand((unsigned int)time(NULL));

    //1、创建员工
    vector<Worker>vWorker;
    createWorker(vWorker);

    //2、员工分组
    multimap<int, Worker>mWorker;
    setGroup(vWorker, mWorker);

    //3、分组显示员工
    showWorkerByGourp(mWorker);

    ////测试
    //for (vector<Worker>::iterator it = vWorker.begin(); it != vWorker.end(); it++)
    //{
    //  cout << "姓名: " << it->m_Name << " 工资: " << it->m_Salary << endl;
    //}


    return 0;
}

Run/Observation Results: This is a syntax fragment, focus on the writing style; run it after completing the context.

Summary:

  • When data exists in key-value pairs, you might consider using map or multimap.
音乐页