一、头文件<algorithm>
①sort函数
- sort使用数组元素默认的大小比较运算符进行排序,只有在需要按照特殊依据进行排序时才需要传入额外的比较函数;
- sort可以给任意对象排序(不一定是内置类型,由此可见sort是模板函数),前提是类型需要定义“小于”运算符,或者在排序时传入一个“小于”函数;
- 排序对象若存在普通数组中,则用sort(a, a+n)的方式调用;
- 排序对象若存在vector中,则用sort(v.begin(), v.end())。
1 #include<algorithm> 2 const int maxn = 10000; 3 int main() 4 { 5 int n, a[maxn]; 6 for(int i=0;i<n;i++){ 7 scanf("%d",&a[i]); 8 } 9 sort(a,a+n); 10 }
②lower_bound函数
- 查找大于或者等于x的第一个位置
- 可以在用sort函数排好序后再使用lower_bound
1 #include<algorithm> 2 const int maxn = 10000; 3 int main() 4 { 5 int n, a[maxn]; 6 for(int i=0;i<n;i++) 7 scanf("%d",&a[i]); 8 sort(a,a+n); 9 scanf("%d",&x); 10 int p = lower_bound(a, a+n, x) - a; //在已排序数组a中寻找x 11 if(a[p]==x) 12 printf("%d found at %d ", x, p+1); 13 }
二、头文件<vector>
①特点:它把一些常用操作“封装”在了vector类型内部(例如:函数size()可以读取其大小)。
②区别于数组:无需另外用一个变量(maxn)指定元素个数。
③优点:可以直接赋值,还可以作为函数的参数或者返回值。
vector是一个模板类:
1 int main() 2 { 3 vector<int> a; //声明一个不定长int型数组a 4 a.push_back(1); //在尾部添加元素1 5 a.pop_back(); //在尾部删除元素 6 cout<<a.size(); //输出a的大小 7 a.resize(4); //修改a的大小为4 8 a.clear(); //清空a,此时a的大小为0 9 bool isEmpty = a.empty(); //a为空,则isEmpty被赋值为true 10 }
三、头文件<set>
定义:set是数学上的集合——每个元素最多只能出现一次。
特点:和sort一样,自定义类型也可以构造set,但必须定义“小于”运算符。
性质:set中元素已从小到大排好序。
题目:输入一个文本,找出所有不同的单词(连续的字母序列),按字典序从小到大输出,单词不区分大小写。
1 #include<iostream> 2 #include<string> 3 #include<set> 4 #include<sstream> 5 using namespace std; 6 7 set<string> dict; //声明string集合 8 string s, buf; 9 10 int main() 11 { 12 while(cin >> s) { //注意:string已经定义了"小于"运算符,可直接使用set保存单词集合 13 for(int i = 0; i < s.length(); i++) //利用了set的性质,一个for循环即可从小到大遍历所有元素 14 if(isalpha(s[i])) //判定s[i]是否为字母 15 s[i] = tolower(s[i]); //全都转为小写 16 else 17 s[i] = ' '; 18 stringstream ss(s); 19 while(ss >> buf) 20 dict.insert(buf); 21 } 22 for(set<string>::iterator it = dict.begin(); it != dict.end(); ++it)//利用了set的性质,一个for循环即可从小到大遍历所有元素 23 cout << *it << " "; //迭代器it的用法之一 24 return 0; 25 }
四、头文件<map>
定义:map就是从键(key)到值(value)的映射。
特点:重载了[]运算符,map像是数组的“高级版”。
举例:用map<string,int> month_name来表示“月份名字到月份编号”的映射,然后用month_name["July"]=7这样的方式来赋值。
题目:输入一些单词,找出所有满足如下条件的单词:该单词不能通过字母重排而得到输入文本中的另外一个单词。字母不区分大小写。
1 #include<iostream> 2 #include<string> 3 #include<cctype> 4 #include<vector> 5 #include<map> 6 #include<algorithm> 7 using namespace std; 8 9 map<string,int> cnt; 10 vector<string> words; 11 12 13 string repr(string s) //将单词s进行标准化 14 { 15 string ans = s; 16 for(int i = 0; i < ans.length(); i++) 17 ans[i] = tolower(ans[i]); 18 sort(ans.begin(), ans.end()); 19 return ans; 20 } 21 22 int main() { 23 int n = 0; 24 string s; 25 while(cin >> s) { 26 if(s[0] == '#') break; 27 words.push_back(s); 28 string r = repr(s); 29 if(!cnt.count(r)) //set和map都支持insert、find、count和remove操作,并且可以按照从小到大的顺序循环遍历其中的元素 30 cnt[r] = 0; 31 cnt[r]++; 32 } 33 vector<string> ans; 34 for(int i = 0; i < words.size(); i++) 35 if(cnt[repr(words[i])] == 1) 36 ans.push_back(words[i]); 37 sort(ans.begin(), ans.end()); 38 for(int i = 0; i < ans.size(); i++) 39 cout << ans[i] << " "; 40 return 0; 41 }
小结:set和map都支持insert、find、count和remove操作,并且可以按照从小到大的顺序循环遍历其中的元素。此外,map还提供了“[]”运算符,使得map可以像数组一样使用。
五、头文件<stack>
- 定义:stack<int> s
- 入栈:push()
- 出栈:pop()
- 取栈顶元素:top()
题目:Uva12096
1 #include<iostream> 2 #include<string> 3 #include<set> 4 #include<map> 5 #include<stack> 6 #include<vector> 7 #include<algorithm> 8 using namespace std; 9 10 #define ALL(x) x.begin(),x.end() 11 #define INS(x) inserter(x,x.begin()) 12 13 typedef set<int> Set; 14 map<Set,int> IDcache; //把集合映射成ID 15 vector<Set> Setcache; //根据ID取集合 16 17 //查找给定集合x的ID。如果找不到,分配一个新ID 18 int ID (Set x) { 19 if (IDcache.count(x)) return IDcache[x]; 20 Setcache.push_back(x); //添加新集合 21 return IDcache[x] = Setcache.size() - 1; 22 } 23 24 int main () { 25 int T; 26 cin >> T; 27 while(T--) { 28 stack<int> s; //题目中的栈 29 int n; 30 cin >> n; 31 for(int i = 0; i < n; i++) { 32 string op; 33 cin >> op; 34 if (op[0] == 'P') s.push(ID(Set())); 35 else if (op[0] == 'D') s.push(s.top()); 36 else { 37 Set x1 = Setcache[s.top()]; s.pop(); 38 Set x2 = Setcache[s.top()]; s.pop(); 39 Set x; 40 if (op[0] == 'U') set_union (ALL(x1), ALL(x2), INS(x)); 41 if (op[0] == 'I') set_intersection (ALL(x1), ALL(x2), INS(x)); 42 if (op[0] == 'A') { x = x2; x.insert(ID(x1)); } 43 s.push(ID(x)); 44 } 45 cout << Setcache[s.top()].size() << endl; 46 } 47 cout << "***" << endl; 48 } 49 return 0; 50 }
六、头文件<queue>
- 定义:queue<int> s
- 入队:push()
- 出队:pop()
- 取队首元素:front()
【优先队列】
区别于队列:先出队列的元素是队列中优先级最高的元素。
声明:priority_queue<int> pq //pq是一个“越小的整数优先级越低的优先队列”
取队首元素:top()
注:自定义类型也可以组成优先队列,但必须为每个元素定义一个优先级。