STL-常用容器

string容器

string构造函数

string本质:类

string和char*区别:

char* 是一个指针

string是一个类,类内部封装了char*,管理这个字符串,是一个char*型的容器。

特点:

string类内部封装了很多成员方法

如:查找find,拷贝copy,删除delete,替换replace,插入insert

string管理char*所分配的内存,不用担心赋值越界和取值越界等,由类内部进行负责

string(); //创建一个空的字符串,例如:string str;

string(const char* s); //使用字符串s初始化

string(const string& str); //使用一个string对象初始化另一个string对象

string(int n, char c); //使用n个字符c初始化

void test01()
{string s1;//创建空字符串,调用无参构造函数cout << s1 << endl;const char* str = "hellow";str = "ds";string s2(str);//把c_string转换成了stringcout << s2 << endl;string s3(s2); //调用拷贝构造函数cout << s3 << endl;string s4(10, 'a');cout << s4 << endl;
}

string赋值操作

功能描述:

  • 给string字符串进行赋值

赋值的函数原型:

string& operator=(const char* s); //char*类型字符串 赋值给当前的字符串

string& operator=(const string& s); //把字符串s赋给当前的字符串

string& operator = (char c); //字符赋值给当前的字符串

string& assign(const char *s); //把字符串s赋给当前的字符串

string& assign(const char *s, int n); //把字符串s的前n个字符赋给当前的字符串

string& assign(const string &s); //把字符串s赋给当前字符串

string& assign(int n, char c); //用n个字符c赋给当前字符串

void test01()
{string s1;s1 = "hello world";cout << "s1: " << s1 << endl;string s2;s2 = s1;cout << "s2: " << s2 << endl;string s3;s3 = 'a';cout << "s3: " << s3 << endl;string s4;s4.assign("hewl");cout << "s4: " << s4 << endl;string s5;s5.assign(s4);cout << "s5: " << s5 << endl;string s6;s6.assign("hello world", 5);cout << "s6: " << s6 << endl;string s7;s7.assign(10, 'a');cout << "s7: " << s7 << endl;}

string字符串拼接

功能描述:

实现在字符串末尾拼接字符串

函数原型:

string& operator+=(const char* str); //重载+=操作符

string& operator+=(const char c); //重载+=操作符

string& operator+=(const string& str); //重载+=操作符

string& append(const char* s); //把字符串s链接到当前字符串结尾

string& append(const char* s, int n); //把字符串s的前n个字符链接到当前字符串结尾

string& append(const string &s); //同operator+=(const string& str)

string& append(conststring &s, int pos, int n);//字符串s中从pos开始的n个字符连接到字符串结尾

void test01()
{string str1 = "我";str1 += ':';cout << str1 << endl;str1 += "爱玩游戏";cout << str1 << endl;string str3 = "I";str3.append(" love ");cout << str3 << endl;string str4 = "lol dwl";str3.append(str4, 3);cout << str3 << endl;str3.append(" game ");cout << str3 << endl;//str3.append(str4, 0, 3);str3.append(str4, 4, 3);cout << str3 << endl;
}

string查找和替换

功能描述:

  • 查找:查找指定字符串是否存在
  • 替换:在指定的位置替换字符串

函数原型:

//查找
void test01()
{string str1 = "abcdefde";int pos = str1.find("de");   //3cout << pos << endl;pos = str1.rfind("de");      //6cout << pos << endl;
}
//替换
void test02()
{string str1 = "abcdefg";str1.replace(1, 3, "1111");cout << str1 << endl; //a1111efg
}

find和rfind区别:

find查找是从左往右,而rfind是从右往左

find找到字符串后返回查找的第一个字符位置,找不到则返回-1

replace在替换时,要指定从哪个位置起,多少个字符,替换成什么样的字符串

string字符串比较

功能描述:

  • 字符串之间比较

比较方式

  • 按字符的ASCII码进行对比

=返回 0

>返回 1

<返回 -1

函数原型:

int compare(const string& s) const; //与字符串比较

int compare(const char* s) const; //与字符串比较

void test01()
{string str1 = "hello";string str2 = "xello";if (str1.compare(str2) == 0){cout << "两个字符串相等" << endl;}else if (str1.compare(str2) > 0){cout << "str1 大于 str2" << endl;}else{cout << "str1 小于 str2" << endl;}
}

compare主要比较的是字符串是否相等,一般不比较大小

string字符存取

string中单个字符存取方式有两种

char& operator[](int n); //通过[]方式取字符

char& at(int n); //通过at方式取字符

void test01()
{string str1 = "hello world";for (int i = 0; i < str1.size(); ++i){cout << str1[i] << " ";}cout << endl;for (int i = 0; i < str1.size(); ++i){cout << str1.at(i) << " ";}
}

string插入和删除

功能描述:

对string字符串进行插入和删除字符操作

函数原型:

void test01()
{string str1 = "hello";//插入str1.insert(1, "111");cout << str1 << endl;//删除str1.erase(1, 3); //从第一个位置开始删除3个字符cout << str1 << endl;
}

插入和删除的下标都从0开始

string子串

功能描述:

  • 从字符串中获取想要的子串

函数原型:

string substr(int pos=0, int n=npos) const; //返回由pos开始的n个字符组成的字符串

void test01()
{string str1 = "abcdef";string str2 = str1.substr(1, 3); //bcdcout << str2 << endl;
}
void test02()
{string email = "lisi@163.com";//从邮件地址中 获取用户名信息//找到@位置int pos = email.find('@');string name = email.substr(0, pos);cout << name << endl;
}

vector容器

vector基本概念

功能:

  • vector数据结构与数组非常相似,也称为单端数组

vector与普通数组区别:

  • 不同之处在于数组是静态空间,而vector可以动态扩展

动态扩展:

  • 并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间。

vector容器的迭代器是支持随机访问的迭代器

vector构造函数

功能描述:

创建vector容器

函数原型:

void printVector(vector<int>& v)
{for (vector<int>::iterator it = v.begin(); it != v.end(); ++it){cout << *it << " ";}cout << endl;
}
void test01()
{vector<int> v1; //默认构造,无参构造for (int i = 0; i < 10; ++i){v1.push_back(i);}printVector(v1);//通过区间方式进行构造vector<int> v2(v1.begin(), v1.end());printVector(v2);//n个elem方式构造vector<int> v3(10, 100);printVector(v3);//拷贝构造vector<int> v4(v3);printVector(v4);
}

vector赋值操作

功能描述:

给vector容器进行赋值

函数原型:

void test01()
{vector<int> v1; //默认构造,无参构造for (int i = 0; i < 10; ++i){v1.push_back(i);}printVector(v1);vector<int> v2 = v1;printVector(v2);//assignvector<int>v3;v3.assign(v2.begin(), v2.end());printVector(v3);vector<int>v4;v4.assign(10, 100);printVector(v4);
}

vector容量和大小

功能描述:

  • 对vector容器的容量和大小操作

函数原型:

void test01()
{vector<int> v1; //默认构造,无参构造for (int i = 0; i < 10; ++i){v1.push_back(i);}printVector(v1);if (v1.empty()){cout << "v1为空!" << endl;}else{cout << "v1不为空!" << endl;cout << "v1的容量大小:" << v1.capacity() << endl;cout << "v1的大小:" << v1.size() << endl;}//重新指定大小//v1.resize(15);v1.resize(15, 10);printVector(v1);v1.resize(5);printVector(v1);
}

vector插入和删除

函数原型:

void test01()
{vector<int> v1; //默认构造,无参构造//尾插for (int i = 0; i < 5; ++i){v1.push_back(i);}printVector(v1);//尾删v1.pop_back();printVector(v1);//插入v1.insert(v1.begin(), 10);printVector(v1);v1.insert(v1.begin(), 2, 20);printVector(v1);//删除,参数也是迭代器v1.erase(v1.begin());printVector(v1);//清空//v1.erase(v1.begin(), v1.end());v1.clear();printVector(v1);
}

vector数据存取

函数原型:

void test01()
{vector<int> v1; //默认构造,无参构造for (int i = 0; i < 10; ++i){v1.push_back(i);}for (int i = 0; i < v1.size(); ++i){cout << v1[i] << " ";}cout << endl;for (int i = 0; i < v1.size(); ++i){cout << v1.at(i) << " ";}cout << endl;cout << v1.front() << endl;cout << v1.back() << endl; 
}

vector互换容器

功能描述:

实现两个容器内元素进行互换

函数原型:

swap(vec); //将vec于本身的元素互换

void test01()
{vector<int> v1; //默认构造,无参构造for (int i = 0; i < 100000; ++i){v1.push_back(i);}cout << "v1的容量大小:" << v1.capacity() << endl;cout << "v1的大小:" << v1.size() << endl;v1.resize(3); //重新指定大小cout << "v1的容量大小:" << v1.capacity() << endl;cout << "v1的大小:" << v1.size() << endl;//巧用swap收缩内存vector<int>(v1).swap(v1);cout << "v1的容量大小:" << v1.capacity() << endl;cout << "v1的大小:" << v1.size() << endl;
}

此匿名对象按照v进行初始化,故此匿名对象会按照v目前所用的个数作为初始化,即初始的容量是v的size大小

vector预留空间

功能描述:

减少vector在动态扩展容量时的扩展次数

函数原型:

reverse(int len); //容器预留len个元素,预留位置不初始化,元素不可访问

void test01()
{vector<int> v1; //默认构造,无参构造//预留空间v1.reserve(100000);int num = 0;int* p = NULL;for (int i = 0; i < 100000; ++i){v1.push_back(i);if (p != &v1[0]){p = &v1[0];num++;}}cout << num << endl; //不预留空间时,num=30//预留空间时,num=1
}

如果数据量较大,可以一开始利用reserve预留空间

deque容器

deque容器基本概念

功能:

双端数组,可以对头端进行插入删除操作

deque与vector区别:

  • vector对于头部的插入删除效率低,数据量越大,效率越低
  • deque相对而言,对头部的插入删除速度会比vector快
  • vector访问元素时的速度会比deque快,这和两者内部实现有关

deque内部工作原理:

deque内部有个中控器,维护每段缓冲区中的内容,缓冲区中存放真实数据

中控器维护的是每个缓冲区的地址,使得使用deque时像一篇连续的内存空间

deque容器的迭代器也是支持随机访问的

deque构造函数

函数原型:

//const打印,防止数据修改
void printDeque(const deque<int>& v)
{for (deque<int>::const_iterator it = v.begin(); it != v.end(); ++it){cout << *it << " ";}cout << endl;
}void test01()
{deque<int> d1;for (int i = 0; i < 10; ++i){d1.push_back(i);}printDeque(d1);deque<int> d2(d1.begin(), d1.end());printDeque(d2);deque<int> d3(d2);printDeque(d3);deque<int> d4(10, 2);printDeque(d4);}

赋值操作

void test01()
{deque<int> d1;for (int i = 0; i < 10; ++i){d1.push_back(i);}printDeque(d1);deque<int> d2 = d1;printDeque(d2);deque<int> d3;d3.assign(d2.begin(), d2.end());printDeque(d3);deque<int> d4;d4.assign(10, 2);printDeque(d4);
}

deque大小操作

deque插入和删除

函数原型:

void test01()
{deque<int> d1;for (int i = 0; i < 10; ++i){d1.push_back(i);}printDeque(d1);d1.push_front(11);printDeque(d1);d1.pop_back();d1.pop_back();printDeque(d1);d1.pop_front();d1.pop_front();printDeque(d1);d1.insert(d1.begin() + 2, 100);printDeque(d1);//删除deque<int>::iterator it = d1.begin();it++;d1.erase(it);printDeque(d1);//区间删除//d1.erase(d1.begin(), d1.end());//清空d1.clear();printDeque(d1);
}

deque数据存取

函数原型:

deque排序

算法:

sort(iterator beg, iterator end); //对beg和end区间内元素进行排序

void test01()
{deque<int> d1;for (int i = 0; i < 10; ++i){d1.push_back(i);}printDeque(d1);d1.push_front(11);d1.push_front(12);d1.push_front(13);printDeque(d1); //13 12 11 0 1 2 3 4 5 6 7 8 9//排序,默认排序规则:从小到大,升序//对于支持随机访问的迭代器的容器,都可以利用sort算法直接排序//vector容器也可以利用sort排序sort(d1.begin(), d1.end());cout << "排序后:" << endl;printDeque(d1);
}

案例:评委打分

void printPerson(vector<Person>& v)
{for (vector<Person>::iterator it = v.begin(); it != v.end(); ++it){cout << "姓名:" << (*it).m_Name << ",平均分:" << (*it).m_Score << endl;}
}
void createPerson(vector<Person>& v)
{string nameSeed = "ABCDE";for (int i = 0; i < 5; ++i){string name = "选手";name += nameSeed[i];int score = 0;Person p(name, score);v.push_back(p);}
}
void setScore(vector<Person>& v)
{for (vector<Person>::iterator it = v.begin(); it != v.end(); ++it){deque<int>d;for (int i = 0; i < 10; ++i){int score = rand() % 41 + 60;d.push_back(score);}//排序sort(d.begin(), d.end());//去掉最高和最低分d.pop_back();d.pop_front();//printDeque(d);//取平均分int sum = 0;for (deque<int>::iterator dit = d.begin(); dit != d.end();++dit){sum += *dit;}int avg = sum / d.size();(*it).m_Score = avg;}
}
void test01()
{//随机种子srand((unsigned int)time(NULL));//初始化五名选手vector<Person> v;createPerson(v);//printPerson(v);//打分数setScore(v);printPerson(v);
}

stack容器

stack基本概念

stack是一种先进后出(First In Last Out)的数据结构,它只有一个出口

栈中只有顶端元素才可被外界使用,因为栈不允许有遍历行为

stack常用接口

void test01()
{stack<int> s;//入栈s.push(10);s.push(20);s.push(30);s.push(40);cout << "栈的大小:" << s.size() << endl;while (!s.empty()){cout << "栈顶元素:" << s.top() << endl;//出栈s.pop();}cout << "栈的大小:" << s.size() << endl;}
  • 入栈:push
  • 出栈:pop
  • 返回栈顶:top
  • 判断栈是否为空:empty
  • 返回栈大小:size

queue容器

queue基本概念

先进先出

队列容器允许从一端新增元素,从另一端移除元素

只有队头和队尾可用,不允许有遍历行为

进数据称为 -- 入队 push

出数据称为 -- 入队 pop

queue常用接口

list容器

list基本概念

功能:将数据进行链式存储

链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的。

链表组成:由一系列结点组成

结点组成:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域

STL中链表是一个双向循环链表

由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只能前移和后移,属于双向迭代器

list的优点:

  • 采用动态存储分配,不会造成内存浪费和溢出
  • 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素

list的缺点:

链表灵活,但空间(指针域)和时间(遍历)额外耗费较大

list的插入和删除操作都不会造成原有list迭代器的失效,这在vector中是不成立的。

总结:STL中list和vector是两个最常被使用的容器,各有优缺点

list构造函数

函数原型:

void printList(const list<int>& l)
{for (list<int>::const_iterator it = l.begin(); it != l.end(); ++it){cout << *it << " ";}cout << endl;
}
void test01()
{list<int> l1;//默认构造l1.push_back(10);l1.push_back(20);l1.push_back(30);l1.push_back(40);printList(l1);list<int>l2(l1.begin(), l1.end());printList(l2);list<int>l3(l2);printList(l3);list<int>l4(10, 2);printList(l4);
}

list赋值和交换

void test01()
{list<int> l1;//默认构造l1.push_back(10);l1.push_back(20);l1.push_back(30);l1.push_back(40);printList(l1);list<int>l2 = l1;printList(l2);list<int>l3;l3.assign(l2.begin(), l2.end());printList(l3);list<int>l4;l4.assign(10, 12);printList(l4);
}
void test02()
{list<int> l1;//默认构造l1.push_back(10);l1.push_back(20);l1.push_back(30);l1.push_back(40);list<int>l4;l4.assign(10, 12);printList(l1);printList(l4);l1.swap(l4);cout << "交换后:" << endl;printList(l1);printList(l4);
}

list大小操作

函数原型:

list插入和删除

函数原型:

void test01()
{list<int> l1;//默认构造//尾插l1.push_back(10);l1.push_back(20);l1.push_back(30);l1.push_back(40);printList(l1);//头插l1.push_front(10);l1.push_front(20);printList(l1);//尾删l1.pop_back();printList(l1);//头删l1.pop_front();printList(l1);l1.insert(l1.begin(), 3, 2);printList(l1);l1.insert(l1.begin(), 1);printList(l1);l1.erase(++l1.begin());//l1.clear();printList(l1);l1.remove(2);printList(l1);
}

尾插:push_back

尾删:pop_back

头插:push_front

头删:pop_front

插入:insert

删除:erase

移除:remove

清空:clear

list数据存取

函数原型:

front(); //返回第一个元素

back(); //返回最后一个元素

迭代器只能用it++或it--,不能it=it+1等,即不能随机访问

list反转和排序

函数原型:

reverse; //反转链表

sort(); //链表排序

所有不支持随机访问迭代器的容器,不可以用标准算法

不支持随机访问的迭代器的容器,内部会提供对应一些算法

bool myCompare(int v1, int v2)
{return v1 > v2;
}
void test01()
{list<int> l1;//默认构造//尾插l1.push_back(10);l1.push_back(20);l1.push_back(30);l1.push_back(40);printList(l1);//头插l1.push_front(80);l1.push_front(70);printList(l1);//反转l1.reverse();printList(l1);//所有不支持随机访问迭代器的容器,不可以用标准算法// 不支持随机访问的迭代器的容器,内部会提供对应一些算法//sort(l1.begin(), l1.end());//排序l1.sort();//默认从小到大,升序printList(l1);l1.sort(myCompare);//降序printList(l1);
}

排序案例

class Person
{
public:Person(string name, int age, int height){m_Name = name;m_Age = age;m_Height = height;}string m_Name;int m_Age;int m_Height;
};
void printLP(list<Person>& l)
{for (list<Person>::iterator it = l.begin(); it != l.end(); ++it){cout << "姓名:" << (*it).m_Name << ",年龄:" << (*it).m_Age << ",身高:" << (*it).m_Height << endl;}
}
bool comPerson(Person p1, Person p2)
{if (p1.m_Age == p2.m_Age){return p1.m_Height > p2.m_Height;}return p1.m_Age < p2.m_Age;
}
void test01()
{list<Person>l;Person p1("刘备", 35, 175);Person p2("曹操", 45, 180);Person p3("孙权", 40, 170);Person p4("赵云", 25, 190);Person p5("张飞", 35, 160);Person p6("关羽", 35, 200);l.push_back(p1);l.push_back(p2);l.push_back(p3);l.push_back(p4);l.push_back(p5);l.push_back(p6);printLP(l);l.sort(comPerson);cout << "排序后=============" << endl;printLP(l);}

set/multiset容器

set基本概念

所有元素都会在插入时自动被排序

本质:set/multiset属于关联式容器,底层结构是用二叉树实现

set和multiset区别:

set不允许容器有重复元素

multiset允许容器有重复元素

set构造和赋值

void printSet(const set<int>& s)
{for (set<int>::const_iterator it = s.begin(); it != s.end(); ++it){cout << *it << " ";}cout << endl;
}
void test01()
{set<int>s;//set插入只有insert,没有其他函数s.insert(10);s.insert(30);s.insert(40);s.insert(20);s.insert(30);printSet(s);set<int>s2 = s;printSet(s2);set<int>s3(s2);printSet(s3);
}

set大小和交换

不能重新定义容器大小,没有resize函数

set插入和删除

函数原型:

void test01()
{set<int>s;//set插入只有insert,没有其他函数s.insert(10);s.insert(30);s.insert(40);s.insert(20);s.insert(30);printSet(s);//删除s.erase(s.begin());printSet(s);s.erase(40);printSet(s);/*s.erase(s.begin(), s.end());printSet(s);*/s.clear();printSet(s);
}

set查找和统计

函数原型:

void test01()
{set<int>s;//set插入只有insert,没有其他函数s.insert(10);s.insert(30);s.insert(40);s.insert(20);s.insert(30);printSet(s);set<int>::iterator pos = s.find(30);if (pos != s.end()){cout << "找到了元素" << *pos << endl;}else{cout << "没找到" << endl;}//统计int sum = s.count(100);cout << sum << endl;
}

pair对组创建

成对出现的数据,利用对组可以返回两个数据

两种创建方式:

void test01()
{//第一种方式pair<string, int> p("tom", 18);cout << "姓名:" << p.first << ",年龄:" << p.second << endl;//第二种方式pair<string, int>p2 = make_pair("jerry", 20);cout << "姓名:" << p2.first << ",年龄:" << p2.second << endl;
}

set容器排序

set容器默认排序规则为从小到大,利用仿函数,可以改变排序规则

class CompareSet
{
public:bool operator()(int v1, int v2)const{return v1 > v2;}
};
void test01()
{set<int>s;//set插入只有insert,没有其他函数s.insert(10);s.insert(30);s.insert(40);s.insert(20);s.insert(30);printSet(s);//在插入数据之后没有办法改变排序规则set<int, CompareSet> s2;s2.insert(10);s2.insert(30);s2.insert(40);s2.insert(20);s2.insert(30);for (set<int, CompareSet>::iterator it = s2.begin(); it != s2.end(); ++it){cout << *it << " ";}cout << endl;
}

set存放自定义数据类型,排序方式要自己定义

class Person
{
public:Person(string name, int age){m_Name = name;m_Age = age;}string m_Name;int m_Age;
};
class ComPerson
{
public:bool operator()(Person p1, Person p2) const{return p1.m_Age < p2.m_Age;}
};void test01()
{//自定义数据类型,都会指定排序规则set<Person, ComPerson>s;Person p1("tony", 18);Person p2("lily", 28);Person p3("son", 16);s.insert(p1);s.insert(p2);s.insert(p3);for (set<Person>::iterator it = s.begin(); it != s.end(); ++it){cout << "姓名:" << (*it).m_Name << ",年龄:" << (*it).m_Age << endl;}}

map/multimap容器

map基本概念

map中所有元素都是pair

pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)

所有元素都会根据元素的键值自动排序

本质:

map/multimap属于关联式容器,底层结构用二叉树实现。

优点:

可根据key值快速找到value值

map和multimap区别:

map不允许容器中有重复key值元素

multimap允许容器中有重复key值元素

map构造和赋值

函数原型:

void printMap(const map<int, int>&m)
{for (map<int, int>::const_iterator it = m.begin(); it != m.end(); ++it){cout << "key: " << (*it).first << ", value: " << (*it).second << 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, 40));printMap(m);cout << "=======================" << endl;map<int, int>m2(m);printMap(m2);cout << "=======================" << endl;map<int, int>m3 = m2;printMap(m3);
}

map大小和交换

函数原型:

map插入和删除

函数原型:

void test01()
{map<int, int>m;//插入方式1m.insert(pair<int, int>(1, 10));//插入方式2m.insert(make_pair(2, 20));//插入方式3m.insert(map<int, int>::value_type(3, 30));//插入方式4m[4] = 40;printMap(m);cout << "=======================" << endl;m.erase(m.begin());printMap(m);cout << "=======================" << endl;m.erase(3);printMap(m);//m.erase(m.begin(), m.end());m.clear();printMap(m);}

map查找和统计

函数原型:

map容器排序

利用仿函数,可以改变排序规则

STL案例 - 员工分组

案例描述:

实现步骤:

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 w;w.m_Name = "员工";w.m_Name += nameSeed[i];w.m_Salary = rand()%10000+10000;v.push_back(w);   }
}
void printWorker(vector<Worker>& w)
{for (vector<Worker>::iterator it = w.begin(); it != w.end(); ++ it){cout << "姓名:" << (*it).m_Name << ",工资:" << it->m_Salary << endl;}
}
void setDepartment(multimap<int, Worker>& d, vector<Worker> worker)
{for (vector<Worker>::iterator it=worker.begin(); it!=worker.end(); ++it){int k = rand() % 3;d.insert(make_pair(k, *it));}
}
void showWorkerByGroup(multimap<int, Worker>& m)
{cout << "策划部门:" << endl;multimap<int, Worker>::iterator it = m.find(CEHUA);int count = m.count(CEHUA);int index = 0;/*while (it != m.end() && (*it).first == CEHUA){cout << "姓名:" << (*it).second.m_Name << ",工资:" << it->second.m_Salary << endl;it++;}cout << "美术部门:" << endl;it = m.find(MEISHU);while (it != m.end() && (*it).first == MEISHU){cout << "姓名:" << (*it).second.m_Name << ",工资:" << it->second.m_Salary << endl;it++;}cout << "研发部门:" << endl;it = m.find(YANFA);while (it != m.end() && (*it).first == YANFA ){cout << "姓名:" << (*it).second.m_Name << ",工资:" << it->second.m_Salary << endl;it++;}*/while (it != m.end() && index < count){cout << "姓名:" << (*it).second.m_Name << ",工资:" << it->second.m_Salary << endl;it++;index++;}cout << "美术部门:" << endl;it = m.find(MEISHU);count = m.count(MEISHU);index = 0;while (it != m.end() && index < count){cout << "姓名:" << (*it).second.m_Name << ",工资:" << it->second.m_Salary << endl;it++;index++;}cout << "研发部门:" << endl;it = m.find(YANFA);count = m.count(YANFA);index = 0;while (it != m.end() && index < count){cout << "姓名:" << (*it).second.m_Name << ",工资:" << it->second.m_Salary << endl;it++;index++;}
}
void test01()
{//创建员工vector<Worker> worker;createWorker(worker);printWorker(worker);//对员工分部门multimap<int, Worker>depeartment;setDepartment(depeartment, worker);showWorkerByGroup(depeartment);
}
int main()
{srand((unsigned int)time(NULL));system("pause");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/140449.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Android 12,调用系统库libft2.so 遇到的各种问题记录

问题前提,Android 12系统,vendor静态库中调用 libft2.so。(vendor静态库中调用libft2.so会简单点,没这么麻烦) 【问题1】 (native:vendor) can not link against libft2 (native:platform) 本地debug尝试修改: 为了本地环境debug调试方便,我找了个 mk文件,在里面添加了…

Centos安装显卡

1、安装基础环境 yum -y install epel-release yum -y install gcc kernel-devel kernel-headers 2.对应内核版本 yum info kernel-devel kernel-headers Cat /proc/version 3、yum安装版本不对应。则去官网手动下载 离线安装对应的rpm&#xff1a; https://pkgs.org/dow…

RPC框架学习

一、设计目标 RPC 框架的目标就是让远程服务调用更加简单、透明&#xff0c;RPC 框架负责屏蔽底层的传输方式&#xff08;TCP 或者 UDP&#xff09;、序列化方式&#xff08;XML/Json/ 二进制&#xff09;和通信细节。服务调用者可以像调用本地接口一样调用远程的服务提供者&a…

eCharts实现漏斗图

需求&#xff1a;像漏斗那样进行层层筛选&#xff0c;进行一个可直接看见过程的图表 效果&#xff1a; 代码&#xff1a; option { //标题title: {text: Funnel,left: left,top: bottom}, //刷新加下载toolbox: {orient: vertical,top: center,feature: {restore: {},saveA…

Spring Cloud版本选择

SpringCloud版本号由来 SpringCloud的版本号是根据英国伦敦地铁站的名字进行命名的&#xff0c;由地铁站名称字母A-Z依次类推表示发布迭代版本。 SpringCloud和SpringBoot版本对应关系 注意事项&#xff1a; 其实SpringBoot与SpringCloud需要版本对应&#xff0c;否则可能会造…

资料分析笔记

统计术语 现期&#xff1a;现在的时间 基期&#xff1a;之前的时间 现期量 基期量 增长量&#xff08;有正负&#xff09; 增长率 【增幅、增速、r】&#xff08;有正负&#xff09; 同比&#xff1a;例&#xff1a;2014年5月 和 2013年5月 环比&#xff1a;例&#xff1a;20…

《算法竞赛·快冲300题》每日一题:“矩阵”

《算法竞赛快冲300题》将于2024年出版&#xff0c;是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码&#xff0c;以中低档题为主&#xff0c;适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 质…

YOLOv5如何训练自己的数据集

文章目录 前言1、数据标注说明2、定义自己模型文件3、训练模型4、参考文献 前言 本文主要介绍如何利用YOLOv5训练自己的数据集 1、数据标注说明 以生活垃圾数据集为例子 生活垃圾数据集&#xff08;YOLO版&#xff09;点击这里直接下载本文生活垃圾数据集 生活垃圾数据集组成&…

005:vue2使用vue-type-writer实现打字机效果

Vue Type Writer是一个Vue.js 2打字机效果组件&#xff0c;支持像打字机一样模仿键入文本。 文章目录 1. 效果2. 安装使用 1. 效果 2. 安装使用 npm 安装 npm install vue-type-writer --save完整代码 <template><div class"app-container home"><…

面向使用者的git与gerrit相关笔记

git与gerrit相关笔记 前言一、gerrit是什么&#xff1f;二、一些配置1.先配置全局email 和name2.gerrit配置ssh key3.可能遇到的问题 三、提交代码和合并冲突常用Git命令三件套严格的要求 总结 前言 本文是介绍什么是gerrit和工作中git与gerrit相关的命令来避免一些提交代码的…

JavaScript中的代理对象(proxy)

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 创建代理对象⭐ 使用代理对象⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友…

负载均衡 —— SpringCloud Netflix Ribbon

Ribbon 简介 Ribbon 是 Netfix 客户端的负载均衡器&#xff0c;可对 HTTP 和 TCP 客户端的行为进行控制。为 Ribbon 配置服务提供者地址后&#xff0c;Ribbon 就可以基于某种负载均衡算法自动帮助服务消费者去请求。Ribbon 默认提供了很多负载均衡算法&#xff0c;例如轮询、随…

leetcode:2446. 判断两个事件是否存在冲突(python3解法)

难度&#xff1a;简单 给你两个字符串数组 event1 和 event2 &#xff0c;表示发生在同一天的两个闭区间时间段事件&#xff0c;其中&#xff1a; event1 [startTime1, endTime1] 且event2 [startTime2, endTime2] 事件的时间为有效的 24 小时制且按 HH:MM 格式给出。 当两个…

使用 PyTorch 的计算机视觉简介 (5/6)

一、说明 本文主要介绍CNN中在pytorch的实现&#xff0c;其中VGG16网络&#xff0c;数据集来源&#xff0c;以及训练过程&#xff0c;模型生成和存储&#xff0c;模型调入等。 二、预训练模型和迁移学习 训练 CNN 可能需要大量时间&#xff0c;并且该任务需要大量数据。但是&am…

python随手小练3

题目&#xff1a; 写出一个判断闰年的python代码&#xff1a; 闰年的条件&#xff1a; 如果N能够被4整除&#xff0c;并且不能被100整除&#xff0c;则是闰年 或者&#xff1a;N能被400整除&#xff0c;也是闰年 即&#xff1a;4年一润并且百年不润&#xff0c;每400年再润一…

Verilog 不同编码风格对综合电路的影响

文章目录 示例 #1示例 #2示例 #3 Verilog是一种硬件描述语言&#xff08;HDL&#xff09;&#xff0c;用于设计数字电路和系统。统一、良好的代码编写风格&#xff0c;可以提高代码的可维护性和可读性。 同样的功能&#xff0c;不同的Verilog 编码风格也会对综合过程产生重大影…

安全远程访问工具

什么是安全远程访问 安全远程访问是指一种 IT 安全策略&#xff0c;允许对企业网络、任务关键型系统或任何机密数据进行授权、受控访问。它使 IT 团队能够根据员工和第三方的角色和工作职责为其提供不同级别的访问权限&#xff0c;安全的远程访问方法可保护系统和应用程序&…

软件设计模式系列之十三——享元模式

1 模式的定义 享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构型设计模式&#xff0c;它旨在减少内存占用或计算开销&#xff0c;通过共享大量细粒度对象来提高系统的性能。这种模式适用于存在大量相似对象实例&#xff0c;但它们的状态可以外部化&#xff08;e…

Android滑动片段

本文所有的代码均存于 https://github.com/MADMAX110/BitsandPizzas 回到BitsandPizzas应用&#xff0c;之前已经创建过创建订单和发出反馈等功能。 修改披萨应用&#xff0c;让它使用标签页导航。在工具条下显示一组标签页&#xff0c;每个选项对应一个不同的标签页。用户单击…

ThreeJS-3D教学一基础场景创建

Three.js 是一个开源的 JS 3D 图形库&#xff0c;用于创建和展示高性能、交互式的 3D 图形场景。它建立在 WebGL 技术之上&#xff0c;并提供了丰富的功能和工具&#xff0c;使开发者可以轻松地构建令人惊叹的 3D 可视化效果。 Three.js 提供了一套完整的工具和 API&#xff0…