C++的STL介绍
vector的定义:vector<typename> name;//可变长的数组
vector<int> array_int;
vector<double> array_double等等
struct node
{
...................
}
vector <node> array_node//结构体数组
vector的数组定义 vector<int> array_int[size]//这样array_int[0]-----array_int[size-1]都是一个vector的容器
vector容器内容的访问
1)通过下标访问,就像访问数组一样。
2)通过迭代器访问 迭代器可以理解为一种类似于指针的东西
vector <int>::iterator it
#include <iostream> #include <vector> using namespace std; int main() { vector <int> array_int; int num; for(int i=1;i<=5;i++) { cin>>num; array_int.push_back(num); } vector<int>::iterator it; for(it=array_int.begin();it!=array_int.end();it++)//通过迭代器访问 cout<<*it<<endl; int len=array_int.size(); for(int i=0;i<len;i++)//通过数组下标访问 cout<<array_int[i]<<" "; return 0; }
vector的常用函数:
push_back();//在最后面添加一个元素
pop_back();//删除最后一个元素
size();//返回一个长度值
claer();//清空vector中的所有元素
insert();//插入一个元素、
insert(it,x);//在迭代器的it位置插入元素x
erase()有两种用法:删除单个元素,删除一个区间内的所有元素
1,删除单个元素erase(it)即删除迭代器为it处的元素
2,erase(first,last)删除【first,last)区间内的所有元素
#include <iostream> #include <stdio.h> #include <vector> using namespace std; int main() { vector<int> array_int; for(int i=1;i<=10;i++) array_int.push_back(i);//向vector数组内添加元素 vector<int>::iterator it;//用迭代器的方法遍历输出vector数组 for(it=array_int.begin();it!=array_int.end();it++) cout<<*it<<" "; cout<<endl; array_int.pop_back();//删除最后一个元素 for(it=array_int.begin();it!=array_int.end();it++)//再次输出查看结果 cout<<*it<<" "; cout<<endl; int len=array_int.size();//获取vector数组的长度 cout<<len<<endl; array_int.clear();//清空数组 cout<<array_int.size()<<endl;//结果应该为0 //重新构建一个vector数组 for(int i=1;i<=10;i++) array_int.push_back(i); vector<int>::iterator it1; for(it1=array_int.begin();it1!=array_int.end();it++) { if(*it1==6)//删除vector数组中的6 { array_int.erase(it); break; } } return 0; }
set集合问题:
set<typename> name;//这点和vector定义一样
set容器内的元素只能通过迭代器(iterator)访问
eg: set<int>::iterator it
#include<iostream> #include <stdio.h> #include <set> using namespace std; int main() { set<int> st; st.insert(1); st.insert(3); st.insert(2); st.insert(5); st.insert(4); set<int>::iterator it; for(it=st.begin();it!=st.end();it++)//set具有自动排序(升序)元素唯一性的功能 cout<<*it<<" "; cout<<endl; set<int>::iterator it1; it1=st.find(2);//set的find()函数用法 set<int>::iterator it2=st.find(60);//find(value)返回对应值的迭代器 cout<<*it1<<" "<<*it2<<endl; //erase();删除元素 st.erase(2);//删除2 set<int>::iterator it3; for(it3=st.begin();it3!=st.end();it3++) cout<<*it3<<" "; cout<<endl; return 0; }
map问题
map<typename1,typename2> mp;
map的访问可以是下标也可以是迭代器访问
#include<iostream> #include<stdio.h> #include <map> using namespace std; int main() { map<char,int> mp; mp['a']=1; mp['b']=2; mp['c']=3; map<char,int>::iterator it; for(it=mp.begin();it!=mp.end();it++)//迭代器访问 cout<<it->first<<" "<<it->second<<endl; return 0; }
map的实例解析:
find(key)查找的功能
erase()这个就不必多说了,删除功能,单个删除或者区间删除两种用法
size()求长度
clear()清楚map容器
#include <stdio.h> #include <iostream> #include <map> using namespace std; int main() { map<char,int>mp; mp['a']=1; mp['b']=2; mp['c']=3; map<char,int>::iterator it=mp.find('b');//按照键的方式查找 map<char,int>::iterator it1=mp.find('d'); cout<<it->first<<" "<<it->second<<endl;//输出b 2 cout<<it1->first<<" "<<it1->second<<endl;//输出的是乱码 mp.erase('b');//删除key='b'的一组值 map<char,int>::iterator it2; for(it=mp.begin();it!=mp.end();it++) cout<<it->first<<" "<<it->second<<endl; /* 输出 a 1 c 3 */ mp.clear();//将这个容器全部清空 //下面补充的是关于map一组值的插入方式 map<int,string>mp2;//学生的学号和姓名 int num=1234; string name="byc"; mp2.insert(pair<int,string>(num,name));//插入语法第一种 num=123;name="zyz"; mp2.insert(map<int,string>::value_type(num,name));//插入语法第二种 map<int,string>::iterator it3; for(it3=mp2.begin();it3!=mp2.end();it3++)//迭代器遍历输出 cout<<it3->first<<" "<<it3->second<<endl; /* 输出 123 zyz 1234 byc 注意map有自动排序的功能 */ return 0; }
priority_queue优先队列
priority_queue优先队列的队首元素一定是当前队列中优先级最高的一个。
priority_queue<typename> name;//语法格式
和队列不一样的是优先队列没有front()函数和把车开()函数,而只能通过top()函数来访问队首的元素,也就是优先级最高的元素
常用函数实列
push(x)入队
top()队首
pop()出队
关于priority_queue内元素的优先级设置
priority_queue<int>q
priority_queue<int, vector<int>,less<int>> q所表达的意思相同
less<int>表示数字越大优先级越大
greater<int>表示数字越小优先级越大
对于结构体的优先级设置
struct node { string name; int price; friend bool operator < (node n1, node n2) { return n1.price<n2.price;//按照价格高的优先级越高 //同样的如果变成价格低的优先级越高就变成n1.price>n2.price } }
#include <stdio.h> #include <iostream> #include <queue>//priority_queue优先队列 using namespace std; struct stu { string name; int score; friend bool operator < (stu s1, stu s2) { return s1.score < s2.score;//分数高的优先级越高 } };//结构体优先级的相关问题 int main() { priority_queue<stu> q; stu t1,t2,t3; t1.name="byc";t1.score=100; t2.name="wj";t2.score=90; t3.name="lxg";t3.score=80; q.push(t1);//入栈 q.push(t2); q.push(t3); cout<<q.top().name<<" "<<q.top().score<<endl; //输出 byc 100 return 0; }
stack和queue
讲到这队与栈的问题就相对简单一点了
stack栈的问题
#include <iostream> #include <stdio.h> #include <stack> using namespace std; int main() { stack<int> s1; s1.push(1);//入栈 s1.push(2);s1.push(3);s1.push(4);s1.push(5);s1.push(6); while(!s1.empty())//判空,当时空的时候返回true { cout<<s1.top()<<" ";//取顶 s1.pop();//出栈 } //输出 6 5 4 3 2 1 栈先进后出的法则 return 0; }
#include <iostream> #include <stdio.h> #include <queue> using namespace std; int main() { queue<int> s1; s1.push(1);//入队 s1.push(2);s1.push(3);s1.push(4);s1.push(5);s1.push(6); while(!s1.empty())//判空 { cout<<s1.front()<<" ";//输出队首元素 s1.pop();//抛出队首元素 //s1.back()表示取队尾元素 } //输出的结果是 1 2 3 4 5 6 先进先出 return 0; }
#include <algorithm>头文件
#include <iostream> #include <stdio.h> #include <algorithm> using namespace std; int main() { int a[5]={1,2,3,4,5}; reverse(a,a+5);//反转 for(int i=0;i<5;i++) cout<<a[i]<<" "; cout<<endl;//输出 5 4 3 2 1 sort(a,a+5);//从小到大排序 for(int i=0;i<5;i++) cout<<a[i]<<" "; cout<<endl;//输出 1 2 3 4 5 sort(a,a+5,greater<int>());//从大到小排序 for(int i=0;i<5;i++) cout<<a[i]<<" ";//输出 5 4 3 2 1 return 0; }
lower_bound upper_bound的用法以及cmp函数
不加比较函数的情况:
int a[]={0,1,2,2,3}; printf("%d\n",lower_bound(a,a+5,2,cmp)-a); printf("%d\n",upper_bound(a,a+5,2,cmp)-a)
结果: 2 4
lower的意义是对于给定的已经排好序的a,key最早能插入到那个位置
0 1 | 2 2 3 所以2最早插入到2的位置
upper的意义是对于给定的已经排好序的a,key最晚能插入到那个位置
0 1 2 2 | 3 所以2最晚插入的位置是4
加了比较函数:
bool cmp(int a,int b) { return a<b; } int main() { int a[]={0,1,2,2,3}; printf("%d\n",lower_bound(a,a+5,2,cmp)-a); printf("%d\n",upper_bound(a,a+5,2,cmp)-a); return 0 ; }
结果仍然2 4 ,可以得出一个结论,cmp里函数应该写的是小于运算的比较
如果加上了等号,lower和upper两个函数功能就刚好反过来了:
bool cmp(int a,int b) { return a<=b; } int main() { int a[]={0,1,2,2,3}; printf("%d\n",lower_bound(a,a+5,2,cmp)-a); printf("%d\n",upper_bound(a,a+5,2,cmp)-a); return 0 ; }
结果 4 2
next_permutation()//全排列
排列(Arrangement),简单讲是从N个不同元素中取出M个,按照一定顺序排成一列,通常用A(M,N)表示。当M=N时,称为全排列(Permutation)。从数学角度讲,全排列的个数A(N,N)=(N)*(N-1)*...*2*1=N!,但从编程角度,如何获取所有排列?那么就必须按照某种顺序逐个获得下一个排列,通常按照升序顺序(字典序)获得下一个排列。
下一个全排列(Next Permutation)
对于给定的任意一种全排列,如果能求出下一个全排列的情况,那么求得所有全排列情况就容易了。好在STL中的algorithm已经给出了一种健壮、高效的方法。
使用next_permutation
如何获取所有全排列情况?STL中的代码非常精妙,利用next_permutation的返回值,判断是否全排列结束(否则将死循环)。对于给定的一个数组,打印其所有全排列只需如下:
#include<iostream> #include <stdio.h> #include <bits/stdc++.h> using namespace std; int main() { int num[5]; for(int i=1;i<=4;i++) num[i]=i; int ans=0; do//全排列 { for(int i=1;i<=4;i++) cout<<num[i]<<" "; cout<<endl; ans++; }while(next_permutation(num+1,num+1+4)); cout<<ans<<endl; return 0; }
fill()函数
#include <iostream> #include <stdio.h> #include <algorithm> using namespace std; int main() { int a[5]={1,2,3,4,5}; fill(a,a+3,111);//将前三个数对变成111; for(int i=0;i<5;i++) cout<<a[i]<<" ";//输出111 111 111 4 5 //fill()函数的作用是将一定区间内的数组重新赋值 return 0; }