C++ STL总结1.vector容器(1)构造(2)基本操作(3)反向迭代(4)插入(5)2.deque 容器(1)遍历容器(2)构造容器(3)赋值操作(4) 插入和删除(5)数据存取3.stack 容器4.queue容器5.string容器(1)构造(2)赋值(3)拼接(4)查找和替换(5)字符串比较(6)字符存取(7)插入和删除(8)子串(9)string容器其他6.set容器和multiset容器(1)遍历容器(2)插入和删除(3)查找和统计(4)set与multiset7.map和multimap容器(1)遍历(2)大小和交换(3)插入和删除(4)查找与统计8.STL常用算法(1)for_each和transform(2)find(3)find_if(4)binary_search(5)adjacent_find(6)count(7)count_if(8)sort排序算法(9)random_shuffle(10)merge(11)reverse(12)copy将容器内指定范围的元素拷贝到另一容器中13.replace和replace_if(14)swap(15)accumulate和fill(16)交集,并集,差集(17)next_permutation(18)lower_bound和upper_bound
2023.6.8
参考文献:
需要头文件#include<vector>
x123using namespace std;4
5//vector构造总结6vector<int>b;7vector<int>a(10); //定义具有10个整型元素的向量(尖括号为元素类型名,它可以是任何合法的数据类型),不具有初值,其值不确定8vector<int>a(10,1); //定义具有10个整型元素的向量,且给出的每个元素初值为19vector<int>a(b); //用向量b给向量a赋值,a的值完全等价于b的值10vector<int>a(b.begin(),b.begin()+3); //将向量b中从0-2(共三个)的元素赋值给a,a的类型为int型11int c[7]={1,2,3,4,5,6,7};//从数组中获得初值12vector<int> a(c, c + 7);13vector<int>a{ 1,2,3,4,5,6,7 };//初始化14vector<int>a = { 1,2,3,4,5,6,7 };//和上面的等价xxxxxxxxxx651void test01()//基本操作2{3 vector<int> a, b;4 int i=0;5 //b为向量,将b的0-2个元素赋值给向量a6 a.assign(b.begin(), b.begin() + 3);7 8 //a含有4个值为2的元素9 a.assign(4, 2);10 11 //返回a的最后一个元素12 a.back();13 14 //返回a的第一个元素15 a.front();16 17 //返回a的第i元素,当且仅当a存在18 a[i];19 20 //清空a中的元素21 a.clear();22 23 //判断a是否为空,空则返回true,非空则返回false24 a.empty();25 26 //删除a向量的最后一个元素27 a.pop_back();28 29 //删除a中第一个(从第0个算起)到第二个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+3(不包括它)结束30 a.erase(a.begin() + 1, a.begin() + 3);31 32 //在a的最后一个向量后插入一个元素,其值为533 a.push_back(5);34 35 //在a的第一个元素(从第0个算起)位置(前面)插入数值5,36 a.insert(a.begin() + 1, 5);37 38 //在a的第一个元素(从第0个算起)位置(前面)插入3个数,其值都为539 a.insert(a.begin() + 1, 3, 5);40 41 //d为数组,在a的第一个元素(从第0个元素算起)的位置(前面)插入b的第三个元素到第5个元素(不包括b+6)42 int d[8];43 a.insert(a.begin() + 1, d + 3, d + 6);44 45 //返回a中元素的个数46 a.size();47 48 //返回a在内存中总共可以容纳的元素个数49 a.capacity();50 51 //将a的现有元素个数调整至10个,多则删,少则补,其值随机52 a.resize(10);53 54 //将a的现有元素个数调整至10个,多则删,少则补,其值为255 a.resize(10, 2);56 57 //将a的容量扩充至100,58 a.reserve(100);59 60 //b为向量,将a中的元素和b中的元素整体交换61 a.swap(b);62 63 //b为向量,向量的比较操作还有 != >= > <= <64 a == b;65}xxxxxxxxxx91void test02()2{3 //反向迭代4 vector<int>a = { 1,2,3,4,5,6,7,8,9,10 };5 for (vector<int>::reverse_iterator iter = a.rbegin(); iter != a.rend(); iter++)6 {7 cout << *iter << endl;//10 9 8 7 6 5 4 3 2 18 }9}| 插入位置都在pos迭代器之前一个位置,返回的迭代器指向插入的第一个元素 | |
| 在迭代器 pos 指定的位置之前插入一个新元素elem,并返回表示新插入元素位置的迭代器。 | iterator insert(pos, elem) |
| 在迭代器 pos 指定的位置之前插入 n 个元素 elem,并返回表示第一个新插入元素位置的迭代器。 | iterator insert(pos, n, elem) |
| 在迭代器 pos 指定的位置之前,插入其他容器(不仅限于vector)中位于[first, last)区域的所有元素,并返回表示第一个新插入元素位置的迭代器。 | iterator insert(pos, first, last) |
| 在迭代器 pos 指定的位置之前,插入初始化列表(用大括号{}括起来的多个元素,中间有逗号隔开)中所有的元素,并返回表示第一个新插入元素位置的迭代器。 | iterator insert(pos, initlist) |
xxxxxxxxxx121void test03()2{3 vector<int>a = { 1,2,3,4,5,6,7,8,9,10 };4 vector<int>::iterator it1 = a.begin() + 4;5 vector<int>::iterator it2 = a.insert(it1, { -1,-2,-3 });6 cout << *it2 << endl;//-17 for (auto k : a)8 {9 cout << k << " ";//1 2 3 4 -1 -2 -3 5 6 7 8 9 1010 }11 cout << endl;12}| pop_back() | 删除 vector 容器中最后一个元素,该容器的大小(size)会减 1, 但容量(capacity)不会发生改变。 |
|---|---|
| erase(pos) | 删除vector容器中pos迭代器指定位置处的元素,并返回指向被删除元素下一个位置元素的迭代器 该容器的大小(size)会减1,但容量(capacity)不会发生改变。 |
| ???swap(beg)、 pop_back() | 先调用 swap() 函数交换要删除的目标元素和容器最后一个元素的位置, 然后使用 pop_back) 删除该目标元素。 |
| erase(beg,end) | 删除vector容器中位于迭代器[beg,end)指定区域内的所有元素,并返回指向被删除区域下一个 位置元素的迭代器。该容器的大小(size)会减小,但容量(capacity)不会发生改变。 |
| remove() | 删除容器中所有和指定元素值相等的元素,并返回指向最后一个元素下一个位置的迭代器。 值得一提的是,调用该函数不会改变容器的大小和容量。 |
| clear() | 删除 vector 容器中所有的元素,使其变成空的 vector 容器。 该函数会改变 vector 的大小(变为 0) ,但不是改变其容量。 |
xxxxxxxxxx201void test04()2{3 vector<int>a = { 1,2,3,4,5,6,6,6,6,7,8,9,10 };4 int size = a.size();5 ptrdiff_t cnt = count(a.begin(), a.end(), 6);//ptrdiff==long long6 auto it = remove(a.begin(), a.end(), 6);7 cout << *it << endl;//78 cout << cnt << endl;//49 for (auto k : a)10 {11 cout << k << " ";//1 2 3 4 5 7 8 9 10 7 8 9 1012 }13 cout << endl;14 a.resize(size - cnt);15 for (auto k : a)16 {17 cout << k << " ";//1 2 3 4 5 7 8 9 1018 }19}20
需要头文件#include<deque>
xxxxxxxxxx101void printdeque(const deque<int>& d)2{3 for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)4//注意迭代器也要换成带const的5 {6 cout << *it << " ";7 //*it = 100;加const后容器中的数据不可以修改了8 }9 cout << endl;10}xxxxxxxxxx141void test01()2{3 deque<int>d1;4 for (int i = 0; i < 10; i++)5 d1.push_front(i+1);6 printdeque(d1);7 //区间赋值8 deque<int>d2(d1.begin(), d1.end());9 printdeque(d2);10 deque<int>d3(10, 100);11 printdeque(d3);12 deque<int>d4(d3);13 printdeque(d4);14}程序输出:
xxxxxxxxxx4110 9 8 7 6 5 4 3 2 1210 9 8 7 6 5 4 3 2 13100 100 100 100 100 100 100 100 100 1004100 100 100 100 100 100 100 100 100 100
xxxxxxxxxx181void test01()2{3 deque<int>d1;4 for (int i = 0; i < 10; i++)5 d1.push_back(i + 1);6 printdeque(d1);7 //operator= 赋值8 deque<int>d2;9 d2 = d1;10 printdeque(d2);11 //assign赋值12 deque<int>d3;13 d3.assign(d2.begin(), d2.end());14 printdeque(d3);15 deque<int>d4;16 d4.assign(10, 100);17 printdeque(d4);18}程序输出:
xxxxxxxxxx411 2 3 4 5 6 7 8 9 1021 2 3 4 5 6 7 8 9 1031 2 3 4 5 6 7 8 9 104100 100 100 100 100 100 100 100 100 100
xxxxxxxxxx261void test01()2{3 deque<int> d1;4 d1.push_back(1);//尾插入15 d1.pop_back()//尾删6 d1.push_front(1);//头插入17 d1.pop_front();//头删8 //插入9 printdeque(d1);//1 2 3 410 d1.insert(d1.begin(), 100);//100 1 2 3 411 d1.insert(d1.begin() + 1, 2, 1000);//100 1000 1000 1 2 3 412 printdeque(d1);13 //按照区间进行插入14 deque<int>d2;15 d2.push_back(1);16 d2.push_back(2);17 d2.push_back(3);18 d1.insert(d1.begin(), d2.begin(), d2.end());19 printdeque(d1);//1 2 320 //删除21 deque<int>::iterator it = d1.begin() + 1;22 d1.erase(it);23 printdeque(d1);// 1 324 d1.clear();25 printdeque(d1);//空26}xxxxxxxxxx61deque d1;2d1[2];//d1中第二个元素3d1.at(2);//d1中第二个元素4//访问头尾元素5cout << "第一个元素为" << d.front() << endl;6cout << "最后一个元素为" << d.back() << endl;需要头文件#include<stack>
xxxxxxxxxx161void test01()2{3 stack<int> s;4 //特点:符合先进后出的数据结构5 s.push(10);6 s.push(20);7 s.push(30);8 s.push(40);9 int m = s.size();10 for (int i = 0; i < m; i++)11 {12 cout << s.top() << " ";//40 30 20 1013 s.pop();14 }15 cout << endl;16}需要头文件#include<queue>
xxxxxxxxxx321class Person2{3public:4 Person(string name, int age)5 {6 this->m_name = name;7 this->m_age = age;8 }9 string m_name;10 int m_age;11};12void test01()13{14 queue<Person>q;15 Person p1("唐僧", 30);16 Person p2("孙悟空", 1000);17 Person p3("猪八戒", 900);18 Person p4("沙僧", 800);19 q.push(p1);20 q.push(p2);21 q.push(p3);22 q.push(p4);23 cout << "队伍人数:" << q.size() << endl;24 while (!q.empty())25 {26 //查看队头27 cout << "队头:姓名" << q.front().m_name << " 年龄" << q.front().m_age << endl;28 //查看队尾29 cout << "队尾:姓名" << q.back().m_name << " 年龄" << q.back().m_age << endl;30 q.pop();31 }32}xxxxxxxxxx121void test01()2{3 string s1;//默认构造,创建一个空的字符串4 cout << "s1=" << s1 << endl;5 const char* str = "hello world!";6 string s2(str);//使用字符串s初始化7 cout << "s2=" << s2 << endl;8 string s3(s2);//使用一个string对象初始化另一个string对象9 cout << "s3=" << s3 << endl;10 string s4(10, 'b');//使用n个字符b初始化11 cout << "s4=" << s4 << endl;12}xxxxxxxxxx41s1=2s2=hello world!3s3=hello world!4s4=bbbbbbbbbb
xxxxxxxxxx221void test01()2{3 string str1;4 str1 = "hello world!";5 cout << "str1 =" << str1 << endl;6 string str2 = str1;7 cout << "str2 =" << str2 << endl;8 //string str3 = 'a';//不知为何不可用9 string str4;10 str4.assign("Hello C艹");11 cout << "str4 =" << str4 << endl;12 string str5;13 str5.assign("hello C艹", 5);//将str4的前五个字符赋给str514 cout << "str5 =" << str5 << endl;15 string str6;16 str6.assign(str5);17 cout << "str6=" << str6 << endl;18 string str7;19 str7.assign(10, 'w');20 cout << "str7=" << str7 << endl;21
22}xxxxxxxxxx61str1 =hello world!2str2 =hello world!3str4 =Hello C艹4str5 =hello5str6=hello6str7=wwwwwwwwww
xxxxxxxxxx211void test01()2{3 string str1 = "我";4 str1 += "爱编程C艹";//拼接字符串5 cout << "str1=" << str1 << endl;6 str1 += "!";//拼接字符7 cout << "str1=" << str1 << endl;8 string str2 = "我也爱C语言";9 str1 += str2;10 cout << "str2=" << str2 << endl;11 string str3 = "I";12 str3.append("love");13 cout << "str3=" << str3 << endl;14 str3.append("gameabcde", 4);15 cout << "str3=" << str3 << endl;16 str3.append(str2);17 cout << "str3=" << str3 << endl;18 str3.append(str2, 4, 7);//从str2的第三个字符开始,截取4个加在末尾,第二个参数为起始字符的位置(位置从0开始计算),第三个参数为字符的长度19 //中文字符占2个位置,英文字符占1个位置20 cout << "str3=" << str3 << endl;21}xxxxxxxxxx71str1=我爱编程C艹2str1=我爱编程C艹!3str2=我也爱C语言4str3=Ilove5str3=Ilovegame6str3=Ilovegame我也爱C语言7str3=Ilovegame我也爱C语言爱C语言
xxxxxxxxxx111void test01()2{3 string str1 = "abcdefgdefg";4 int pos1 = str1.find("de");5 cout << "pos1=" << pos1 << endl;6 int pos2 = str1.find("df");//找不到则返回-17 cout << "pos2=" << pos2 << endl;8 //rfind是最后一次出现的位置,find是第一次出现的位置9 int pos3 = str1.rfind("de");10 cout << "pos3=" << pos3 << endl;11}xxxxxxxxxx31pos1=32pos2=-13pos3=7
xxxxxxxxxx61void test02()2{3 string str1 = "abcdefg";4 str1.replace(1, 3, "1111");//从1号位置起 3个字符 替换为“1111”5 cout << "str1=" << str1 << endl;6}xxxxxxxxxx11str1=a1111efg
xxxxxxxxxx171void test01()2{3 string str1 = "hfllo";4 string str2 = "hello";5 if (str1.compare(str2) == 0)6 {7 cout << "str1等于str2" << endl;8 }9 else if (str1.compare(str2) > 0)10 {11 cout << "str1大于str2" << endl;12 }13 else14 {15 cout << "str1小于str2" << endl;16 }17}//通过逐字符比较ASCII值,大于为1,小于为-1,等于为0,以第一个不一样的字符为准xxxxxxxxxx11str1大于str2
xxxxxxxxxx141void test01()2{3 string str = "hello";4 for (int i = 0; i < 5; i++)5 cout << str[i] << " ";6 cout << endl;7 for (int i = 0; i < 5; i++)8 cout << str.at(i) << " ";9 cout << endl;10//改字符11 str[0] = 'x';12 str.at(1) = 'y';13 cout << str << endl;14}xxxxxxxxxx31h e l l o2h e l l o3xyllo
xxxxxxxxxx101void test01()2{3 string str1="abcdefgh";4 str1.insert(2, "xxx");5 cout << str1 << endl;6 str1.erase(2, 3);//删去从2开始的3个字符7 cout << str1 << endl;8 str1.insert(2, 3, 'x');9 cout << str1 << endl;10}xxxxxxxxxx31abxxxcdefgh2abcdefgh3abxxxcdefgh
xxxxxxxxxx191int main()2{3 cout << "输入邮箱账号以登录游戏" << endl;4 string email;5 //cin >> email;6 email = "handsome_boy@mail2.sysu.edu.cn";7 int pos = email.find('@');8 if (pos == -1)9 {10 cout << "邮箱账号有误" << endl;11 }12 else13 {14 string name;15 name = email.substr(0, pos);16 cout << "你好," << name << ",欢迎进入游戏" << endl;17 }18 return 0;19}xxxxxxxxxx21输入邮箱账号以登录游戏2你好,handsome_boy,欢迎进入游戏
string s;
!=, <, <=, >, >= 惯有操作 任何一个大写字母都小于任意的小写字母xxxxxxxxxx91void test01()2{3 string s("abc");4 cout << s << endl;5 cout << s.size() << endl;6 cout << strlen(s.c_str()) << endl;7 s.~basic_string();8 cout << s << endl;9}xxxxxxxxxx41abc23334
xxxxxxxxxx131void test02()2{3 stringstream sstream;4 string strresult;5 int val = 12345;6 sstream << val;7 sstream >> strresult;8 cout << strresult << endl;9 sstream.clear();10 sstream << "4321";11 sstream >> val;12 cout << val << endl;13}xxxxxxxxxx211234524321
xxxxxxxxxx101void test03()2{3 //把string字符串转化为C风格的字符串4 string s = "abcdefg";5 char str[1000];6 strcpy(str, s.c_str());7 str[0] = 'p';8 str[5] = 'u';9 cout << str << endl;10}xxxxxxxxxx11pbcdeug
需要头文件#include<set>
set不允许容器中有重复的元素
multiset允许容器中有重复的元素
其他操作基本一致
xxxxxxxxxx26123using namespace std;4void printset(const set<int>&s)5{6 if (s.empty())7 {8 cout << "set数组为空" << endl;9 return;10 }11 for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)12 cout << *it << " ";13 cout << endl;14}15
16void printmultiset(const multiset<int>& m)17{18 if (m.empty())19 {20 cout << "multiset数组为空" << endl;21 return;22 }23 for (multiset<int>::const_iterator it = m.begin(); it != m.end(); it++)24 cout << *it << " ";25 cout << endl;26}xxxxxxxxxx281void test01()2{3 set<int>s;4 s.insert(10);5 s.insert(20);6 s.insert(30);7 s.insert(40);8 s.insert(50);9 s.insert(60);10 s.insert(70);11 s.insert(80);12 s.insert(90);13 s.insert(100); 14 s.insert(110);15 s.insert(120);16 printset(s);17 set<int>::iterator it = s.begin();18 set<int>::iterator it2;19 it2 = s.erase(++++it);//删除迭代器所指元素,返回下一个元素的迭代器20 printset(s);21 set<int>::iterator it1 = s.end();22 s.erase(it2, ----it1);//删除区间[it2,----it1)的所有元素,返回下一个元素的迭代器23 printset(s);24 s.erase(110);//删除值为110的元素25 printset(s);26 s.clear();//清空set容器27 printset(s);28}程序输出:
xxxxxxxxxx5110 20 30 40 50 60 70 80 90 100 110 120210 20 40 50 60 70 80 90 100 110 120310 20 110 120410 20 1205set数组为空
xxxxxxxxxx251void test01()2{3 set<int>s;4 s.insert(10);5 s.insert(20);6 s.insert(30);7 s.insert(40);8 s.insert(30);9 s.insert(60);10 s.insert(70);11 s.insert(80);12 s.insert(70);13 s.insert(100);14 s.insert(110);15 s.insert(120);16 printset(s);17 set<int>::iterator it1;18 it1 = s.find(70);//查找70是否存在,若存在,返回该键的元素的迭代器,若不存在,返回set.end()19 if (it1 != s.end()) 20 cout << *it1 << endl; 21 else 22 cout << "未找到元素" << endl;23 int num = s.count(30);24 cout << num << endl;//对于set而言,统计的结果只有0和125}程序输出:
xxxxxxxxxx3110 20 30 40 60 70 80 100 110 12027031
xxxxxxxxxx261void test01()2{3 multiset<int>s;4 s.insert(10);5 s.insert(20);6 s.insert(30);7 s.insert(40);8 s.insert(30);9 s.insert(60);10 s.insert(70);11 s.insert(80);12 s.insert(70);13 s.insert(100);14 s.insert(110);15 s.insert(120);16 printmultiset(s);17 multiset<int>::iterator it1;18 it1 = s.find(70);19//查找70是否存在,若存在,返回该键的元素的迭代器,若不存在,返回set.end()20 if (it1 != s.end()) 21 cout << *(--it1) << endl; 22 else 23 cout << "未找到元素" << endl;24 int num = s.count(30);25 cout << num << endl;//对于multiset而言,统计的结果不只有0和126}程序输出:
xxxxxxxxxx3110 20 30 30 40 60 70 70 80 100 110 12026032
xxxxxxxxxx271void test02()2{3 set<int>s;4 s.insert(20);5 s.insert(20);6 s.insert(30);7 s.insert(40);8 s.insert(30);9 s.insert(60);10 s.insert(70);11 s.insert(80);12 s.insert(70);13 s.insert(100);14 s.insert(110);15 s.insert(120);16 printset(s);17 pair<set<int>::iterator, bool> ret = s.insert(10);18 if (ret.second)19 cout << "第一次插入成功" << endl;20 else 21 cout << "第一次插入失败" << endl; 22 pair<set<int>::iterator, bool> ret1 = s.insert(10);23 if (ret1.second)24 cout << "第二次插入成功" << endl;25 else26 cout << "第二次插入失败" << endl;27}程序输出:
xxxxxxxxxx3120 30 40 60 70 80 100 110 1202第一次插入成功3第二次插入失败
需要头文件#include<map>
map中所有元素都是pair
pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
所有元素都会根据元素键值自动排序
map/multimap属于关联式容器,底层结构是用二叉树实现
优点:可以根据key值快速找到value值
map和multimap区别:
map不允许容器中有重复key值元素
multimap允许容器中有重复key值元素
xxxxxxxxxx29123using namespace std;4void printmap(const map<int, int>& m)5{6 if (m.empty())7 {8 cout << "map容器为空" << endl;9 return;10 }11 for (map<int, int>::const_iterator it = m.begin(); it != m.end(); it++)12 cout << "学号:" << (*it).first << " 分数:" << it->second << endl;13 cout << endl;14}15void test01() 16{ 17 map<int,int>m; 18 m.insert(pair<int, int>(1, 60)); 19 m.insert(pair<int, int>(2, 95)); 20 m.insert(pair<int, int>(4, 73)); 21 m.insert(pair<int, int>(3, 81)); 22 printmap(m); //会按照key值(学号)自动排序 23 24 map<int, int>m2(m); //拷贝构造 25 printmap(m2); 26 map<int, int>m3; 27 m3 = m2; 28 printmap(m3); 29} 程序输出:
xxxxxxxxxx141学号:1 分数:602学号:2 分数:953学号:3 分数:814学号:4 分数:7356学号:1 分数:607学号:2 分数:958学号:3 分数:819学号:4 分数:731011学号:1 分数:6012学号:2 分数:9513学号:3 分数:8114学号:4 分数:73
xxxxxxxxxx41map<int,int> ma;2ma.size();3map<int,int>ma1;4ma.swap(ma1);xxxxxxxxxx241void test01()2{3 map<int, int>m;4 //15 m.insert(pair<int, int>(1, 60));6 m.insert(pair<int, int>(3, 95));7 m.insert(pair<int, int>(4, 73));8 m.insert(pair<int, int>(5, 81));9 //210 m.insert(make_pair(2, 10));11 //312 m.insert(map<int, int>::value_type(6, 30));13 //414 m[7] = 40;15//这种插数方法和其他的不同在于可以修改已经插入的key对应的value16 printmap(m);17 //删除18 m.erase(m.begin(), ++++m.begin());19 printmap(m);20 m.erase(4);//按照key删除21 printmap(m);22 m.clear();23 printmap(m);24}程序输出:
xxxxxxxxxx181学号:1 分数:602学号:2 分数:103学号:3 分数:954学号:4 分数:735学号:5 分数:816学号:6 分数:307学号:7 分数:4089学号:3 分数:9510学号:4 分数:7311学号:5 分数:8112学号:6 分数:3013学号:7 分数:401415学号:3 分数:9516学号:5 分数:8117学号:6 分数:3018学号:7 分数:40
xxxxxxxxxx161void test01()2{3 map<int, int>m;4 m.insert(pair<int, int>(1, 60));5 m.insert(pair<int, int>(3, 95));6 m.insert(pair<int, int>(4, 73));7 m.insert(pair<int, int>(5, 81));8 m.insert(pair<int, int>(2, 84));9 map<int, int>::iterator it;10 it = m.find(4);11 if (it != m.end())12 cout << it->second << endl;//7313 else14 cout << "编号不存在" << endl;15 cout << m.count(4) << endl;//116}以下除特别说明,都需要#include<algorithm>头文件
xxxxxxxxxx111void test01()2{3 vector<int>v;4 for (int i = 0; i < 10; i++)5 v.push_back(i + 1);6 vector<int>vtarget;7 vtarget.resize(v.size());8 transform(v.begin(), v.end(), vtarget.begin(), Transform());9//101 102 103 104 105 106 107 108 109 11010 for_each(vtarget.begin(), vtarget.end(), myprint());11}| find | 查找元素 |
|---|---|
| find_if | 按条件查找元素 |
| adjacent_find | 查找相邻重复元素 |
| binary_search | 二分查找法 |
| count | 统计元素个数 |
| count_if | 按条件统计元素个数 |
功能描述:.查找指定元素, 找到返回指定元素的选代器, 找不到返回结束选代器end()
函数原型 :
find(iterator beg, iterator end, value);
按值查找元素,找到返回指定位置选代器,找不到返回结束选代器位置
beg 开始迭代器
end结束迭代器
value查找的元素
xxxxxxxxxx151void test01()2{3 vector<int>v;4 for (int i = 0; i < 10; i++)5 {6 v.push_back(i + 1);7 }8 vector<int>::iterator it = find(v.begin(), v.end(), 5);9 if (it == v.end())10 {11 cout << "未找到" << endl;12 }13 else14 cout << "找到:" << *it << endl;//找到:515}功能描述:
按条件查找元素
函数原型:.find_if(iterator beg, iterator end, _Pred);
按值查找元素,找到返回指定位置选代器,找不到返回结束选代器位置
beg开始迭代器
end结束迭代器
_Pred函数或者谓词(返回bool类型的仿函数)
xxxxxxxxxx191class mycompare2{3public:4 bool operator()(int a)5 {6 return a > 5;7 }8};9void test01()10{11 vector<int>v;12 for (int i = 0; i < 10; i++)13 v.push_back(i + 1);14 vector<int>::iterator it = find_if(v.begin(), v.end(), mycompare());15 if (it == v.end())16 cout << "未找到" << endl;17 else18 cout << "找到" << *it << endl;//找到619}查找指定的元素,查到返回true,否则返回false
注意:在无序序列中不可用,因为结果会出错
降序也不行,只能用于升序序列
xxxxxxxxxx81void test01()2{3 vector<int>v={0,1,2,3,4,5,6,7,8};4 if (binary_search(v.begin(), v.end(), 6))5 cout << "找到了" << endl;6 else7 cout << "未找到" << endl;8}//找到了查找相邻重复元素,返回相邻元素的第一个位置的迭代器
少用,但是考试会考
xxxxxxxxxx91void test01()2{3 vector<int>v={0,2,0,3,1,4,3,3,2};4 vector<int>::iterator pos = adjacent_find(v.begin(), v.end());5 if (pos == v.end())6 cout << "未找到" << endl;7 else8 cout << *pos << endl;9}//输出3统计元素个数
xxxxxxxxxx61void test01()2{3 vector<int>v={0,1,2,3,5,3,3,6,8};4 int cou = count(v.begin(), v.end(), 3);5 cout << cou << endl;6}//输出3xxxxxxxxxx141class greaterfive2{3public:4 bool operator()(int a)5 {6 return a > 5;7 }8};9void test01()10{11 vector<int>v={0,1,2,7,5,6,3,6,8};12 int cou = count_if(v.begin(), v.end(), greaterfive());13 cout << cou << endl;14}程序输出:
xxxxxxxxxx114
xxxxxxxxxx161void myprint(int val)2{3 cout << val << " ";4}5void test01()6{7 vector<int>v={10,30,50,20,40,90};8 for_each(v.begin(), v.end(), myprint);9 cout << endl;10 sort(v.begin(), v.end());11 for_each(v.begin(), v.end(), myprint);12 cout << endl;13 sort(v.begin(), v.end(), greater<int>());14 for_each(v.begin(), v.end(), myprint);15 cout << endl;16}程序输出:
xxxxxxxxxx3110 30 50 20 40 90210 20 30 40 50 90390 50 40 30 20 10
xxxxxxxxxx61void test01()2{3 srand((unsigned int)time(NULL));4 vector<int>v={0,1,2,3,4,5,6,7,8,9};5 random_shuffle(v.begin(), v.end());//随机打乱v的排序6}可以把两个有序序列合在一起,形成一个新的有序序列
xxxxxxxxxx191void myprint(int val)2{3 cout << val << " ";4}5void test01()6{7 vector<int>v1;8 vector<int>v2;9 for (int i = 0; i < 10; i++)10 {11 v1.push_back(i);12 v2.push_back(i + 1);13 }14 vector<int>vTarget;//目标容器15 vTarget.resize(v1.size() + v2.size());16 merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());17 for_each(vTarget.begin(), vTarget.end(), myprint);18 cout << endl;19}程序输出:
xxxxxxxxxx110 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10
逆序
xxxxxxxxxx131void myprint(int val)2{3 cout << val << " ";4}5void test01()6{7 vector<int>v={10,30,40,50,20};8 for_each(v.begin(), v.end(), myprint);9 cout << endl;10 reverse(v.begin(), v.end());11 for_each(v.begin(), v.end(), myprint);12 cout << endl;13}程序输出:
xxxxxxxxxx2110 30 40 50 20220 50 40 30 10
注意:新容器需要预留空间
xxxxxxxxxx131void myprint(int val)2{3 cout << val << " ";4}5void test01()6{7 vector<int>v={10,30,40,50,20};8 vector<int>v2;9 v2.resize(v.size());10 copy(v.begin(), v.end(), v2.begin());11 for_each(v2.begin(), v2.end(), myprint);12 cout << endl;13}程序输出:
xxxxxxxxxx1110 30 40 50 20
replace将容器内指定范围的旧元素修改为新元素
replace_if将区间内满足条件替换成指定元素
xxxxxxxxxx241void myprint(int val)2{3 cout << val << " ";4}5class compare6{7public:8 bool operator()(int a)9 {10 return a >= 40;11 }12};13void test01()14{15 vector<int>v={10,30,40,30,20,10,30,40,50,20};16 for_each(v.begin(), v.end(), myprint);17 cout << endl;18 replace(v.begin(), v.begin() + 4, 30, 300);19 for_each(v.begin(), v.end(), myprint);20 cout << endl;21 replace_if(v.begin(), v.end(), compare(), 66);22 for_each(v.begin(), v.end(), myprint);23 cout << endl;24}程序输出:
xxxxxxxxxx3110 30 40 30 20 10 30 40 50 20210 300 40 300 20 10 30 40 50 20310 66 66 66 20 10 30 66 66 20
交换
xxxxxxxxxx271void myprint(int val)2{3 cout << val << " ";4}5//swap交换两个同种类型容器的元素6void test01()7{8 vector<int>v={10,30,40,30,20,10,30,40,50,20};9 vector<int>v1;10 for (int i = 0; i < 10; i++)11 v1.push_back(i + 1);12 for_each(v.begin(), v.end(), myprint);13 cout << endl;14 for_each(v1.begin(), v1.end(), myprint);15 cout << endl;16 swap(v, v1);17 for_each(v.begin(), v.end(), myprint);18 cout << endl;19 for_each(v1.begin(), v1.end(), myprint);20 cout << endl;21}22void test02()//也可以swap两个数23{24 int a = 3, b = 4;25 swap(a, b);26 cout << a << " " << b << endl;//4 327}程序输出:
xxxxxxxxxx5110 30 40 30 20 10 30 40 50 2021 2 3 4 5 6 7 8 9 1031 2 3 4 5 6 7 8 9 10410 30 40 30 20 10 30 40 50 2054 3
需要头文件#include<numeric>
accumulate计算容器元素累计总和
fill向容器中添加元素
xxxxxxxxxx231void myprint(int val)2{3 cout << val << " ";4}5void test01()6{7 vector<int>v{10,30,40,30,20,10,30,40,50,20};8 for_each(v.begin(), v.end(), myprint);9 cout << endl;10 int total=accumulate(v.begin(), v.end(), 0);11//第三个参数表示起始累加值,0表示最后结果加012 cout << total << endl;13}14void test02()15{16 vector<int>v;17 v.resize(10);18 for_each(v.begin(), v.end(), myprint);19 cout << endl;20 fill(v.begin(), v.end() - 2, 6);21 for_each(v.begin(), v.end(), myprint);22 cout << endl;23}程序输出:
xxxxxxxxxx4110 30 40 30 20 10 30 40 50 202280030 0 0 0 0 0 0 0 046 6 6 6 6 6 6 6 0 0
set_intersection求两个容器的交集
set_union并集
set_difference差集
xxxxxxxxxx321void myprint(int val)2{3 cout << val << " ";4}5void test01()6{7 vector<int>v={1,2,3,4,5,6,7,8,9,10};8 for_each(v.begin(), v.end(), myprint);9 cout << endl;10 vector<int>v1={5,6,7,8,9,10,11,12,13,14,15};11 for_each(v1.begin(), v1.end(), myprint);12 cout << endl;13 vector<int>vTarget;14 vTarget.resize(min(v.size(), v1.size()));//min是algorithm的算法15 cout << "intersection:" << endl;16 vector<int>::iterator itEnd=set_intersection(v.begin(), v.end(), v1.begin(), v1.end(),vTarget.begin());17 for_each(vTarget.begin(), itEnd , myprint);//itEnd为数据结束的位置,可避免输出大量018 cout << endl;19 //20 vTarget.resize(v.size() + v1.size());21 cout << "union:" << endl;//注意:使用set_union必须保证两个集合都是有序序列22 itEnd=set_union(v.begin(), v.end(), v1.begin(), v1.end(), vTarget.begin());23 for_each(vTarget.begin(), itEnd, myprint);24 cout << endl;25 //26 vTarget.resize(max(v.size(), v1.size()));//max是algorithm的算法27 cout << "difference between v & v1:" << endl;28 itEnd=set_difference(v.begin(), v.end(), v1.begin(), v1.end(), vTarget.begin());29 //v和v1的差集表示在v中不在v1中的部分30 for_each(vTarget.begin(), itEnd, myprint);31 cout << endl;32}程序输出:
xxxxxxxxxx811 2 3 4 5 6 7 8 9 1025 6 7 8 9 10 11 12 13 14 153intersection:45 6 7 8 9 105union:61 2 3 4 5 6 7 8 9 10 11 12 13 14 157difference between v & v1:81 2 3 4
全排列
xxxxxxxxxx171void test01()2{3 vector<int>vec;4 for (int i = 0; i < 3; i++)5 {6 vec.emplace_back(i + 1);7 }8 for (auto k : vec)9 cout << k << " ";10 cout << endl;11 while (next_permutation(vec.begin(), vec.end()))12 {13 for (auto k : vec)14 cout << k << " ";15 cout << endl;16 }17}程序输出:
xxxxxxxxxx611 2 321 3 232 1 342 3 153 1 263 2 1
lower_bound( )和upper_bound( )都是利用二分查找的方法在一个排好序的数组中进行查找的。
在从小到大的排序数组中,lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
也可以用于vector容器,返回值是迭代器
xxxxxxxxxx201const int maxn = 100000 + 10;2const int INF = 2 * int(1e9) + 10;34int cmd(int a, int b) {5 return a > b;6}7int main() {8 int num[6] = { 1,2,4,7,15,34 };9 sort(num, num + 6); //按从小到大排序 10 int pos1 = lower_bound(num, num + 6, 7) - num; //返回数组中第一个大于或等于被查数的值 11 int pos2 = upper_bound(num, num + 6, 7) - num; //返回数组中第一个大于被查数的值12 cout << pos1 << " " << num[pos1] << endl;//3 713 cout << pos2 << " " << num[pos2] << endl;//4 1514 sort(num, num + 6, cmd); //按从大到小排序15 int pos3 = lower_bound(num, num + 6, 7, greater<int>()) - num; //返回数组中第一个小于或等于被查数的值 16 int pos4 = upper_bound(num, num + 6, 7, greater<int>()) - num; //返回数组中第一个小于被查数的值 17 cout << pos3 << " " << num[pos3] << endl;//2 718 cout << pos4 << " " << num[pos4] << endl;//3 419 return 0;20}