320 likes | 542 Views
STL in ACM. RoBa. STL: Standard Template Library 标准模版库 一些重要的概念 : 容器 (container): <vector> <list> <set> <map> … 迭代器 (iterator): 指针. <vector> 内部实现 : 数组 vector <T, Alloc> 支持操作 : begin(), end(), size(), clear(), empty(), [ ] push_back(), pop_back() insert() O(N) erase() O(N)
E N D
STL in ACM RoBa
STL: Standard Template Library 标准模版库 一些重要的概念: 容器(container): <vector> <list> <set> <map> … 迭代器(iterator): 指针
<vector>内部实现: 数组 vector <T, Alloc> 支持操作: begin(), end(), size(), clear(), empty(), [ ] push_back(), pop_back() insert() O(N) erase() O(N) 可以用于数组大小不定且空间紧张的情况
Sample: TOJ1743 King’s Treasure #include <cstdio> #include <vector> using namespace std; vector <int> a[240010]; int main() { int cases,n,i,t,head,tail,src,pans; scanf("%d",&cases); while (cases--) { scanf("%d",&n); for (i = 1 ; i <= n ; i++) a[i].clear(); for (i = 2 ; i <= n ; i++) { scanf("%d",&t); a[i].push_back(t); a[t].push_back(i); } …Full Code
Iterator用法举例: #include <vector> #include <cstdio> using namespace std; int main() { int n,i; vector <int> vi; vector <int>::iterator itr; while (scanf("%d",&n) != EOF) vi.push_back(n); for (i = 0 ; i < vi.size() ; i++) printf("%d\n",vi[i]); for (itr = vi.begin() ; itr != vi.end() ; itr++) printf("%d\n",*itr); return 0; }
<deque>类似<vector> 支持push_front()和pop_front() <stack>是<vector>的精简版:) 支持push(), pop(), top() <queue>是<deque>的精简版 支持push(), pop(), front(), back()
<list>内部实现: 双向链表 list<T, Alloc> 支持操作: begin(), end(), size(), clear(), empty() push_back(), pop_back() push_front(), pop_front() insert() O(1) erase() O(1) sort() O(nlogn),不同于<algorithm>中的sort
<set>内部实现: 红黑树 set<Key, Compare, Alloc> insert() O(logn) erase() O(logn) find() O(logn)找不到返回a.end() lower_bound() O(logn)查找第一个不小于k的元素 upper_bound() O(logn)查找第一个大于k的元素 equal_range() O(logn)返回pair<lower,upper> <multiset>允许重复元素
用法: struct SS {int x,y;}; struct ltstr { bool operator() (SS a, SS b) {return a.x < b.x;} }; int main() { set <SS, ltstr> st; … }
UVA 105 The Skyline Problem 给定一些楼房的范围和高度,求出他们的轮廓。 Input: 1 11 5 2 6 7 3 13 9 12 7 16 14 3 25 19 18 22 23 13 29 24 4 28 Output: 1 11 3 13 9 0 12 7 16 3 19 18 22 3 23 13 29 0 维护一个BST,可以得到复杂度O(nlogn)的算法 可以使用<multiset>简化编程 Code here
<map>内部实现: pair<key,value>组成的红黑树 map<Key, Data, Compare, Alloc> insert() O(logn) erase() O(logn) find() O(logn)找不到返回a.end() lower_bound() O(logn)查找第一个不小于k的元素 upper_bound() O(logn)查找第一个大于k的元素 equal_range() O(logn)返回pair<lower,upper> [key]运算符 O(logn)*** <multimap>允许重复元素, 没有[]运算符
TOJ 1378 Babelfish Code: (0.4k) #include <cstdio> #include <string> #include <map> using namespace std; map <string,string> mp; int main() { char buf[100],s1[100],s2[100]; while (gets(buf)) { if (strlen(buf) == 0) break; sscanf(buf,"%s%s",s1,s2); mp[(string)s2] = (string)s1; } …
… while (gets(buf)) { if (mp.find((string)buf) != mp.end()) printf("%s\n",mp[(string)buf].c_str()); else printf("eh\n"); } return 0; } A challenge: TOJ 2175 Computer Games
<priority_queue>内部实现: 堆 priority_queue<T, Sequence, Compare> 支持操作: push() O(logn) pop() O(logn) top() O(1) See also: push_heap(), pop_heap() … in <algorithm>
用法举例: #include <queue> #include <vector> using namespace std; priority_queue <int> maxheap; //int最大堆 struct ltstr { bool operator()(int a,int b) {return a > b;} }; priority_queue <int,vector<int>,ltstr> minheap; //int最小堆
<hash_map>内部实现: Hash表, of course hash_map<Key, Data, HashFcn, EqualKey, Alloc> 重载HashFcn和EqualKey 支持操作: insert(); O(1) earse(); O(1) [ ]; O(1) 示例:Again TOJ 1378 Babelfish See also: <hash_set> <hash_multimap> <hash_multiset>
#include <cstdio> #include <hash_map.h> //?? #include <string> using namespace std; struct calc_hash { size_t operator()(string str) const { unsigned long h = 0; int i; for (i = 0 ; i < str.size() ; i++) { h <<= 5; h |= str[i] - 'a'; } return (size_t)h; //h%M?? } };
struct eqstr { bool operator()(string s1, string s2) {return s1 == s2;} }; //本题此处可省略 int main() { hash_map<string,string,calc_hash> hp; char buf[100],s1[20],s2[20]; while (gets(buf)) { if (strlen(buf) == 0) break; sscanf(buf,"%s%s",s1,s2); hp[(string)s2] = (string)s1; } while (gets(buf)) { if (hp.find((string)buf) != hp.end()) printf("%s\n",hp[(string)buf].c_str()); else printf("eh\n"); } return 0; }
<algorithm> 1.sort() void sort(RandomAccessIterator first, RandomAccessIterator last); void sort(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering comp); 区间[first,last) Quicksort,复杂度O(nlogn) (n=last-first,平均情况和最坏情况)
用法举例: 1.从小到大排序(int, double, char, string, etc) const int N = 5; int main() { int a[N] = {4,3,2,6,1}; string str[N] = {“TJU”,”ACM”,”ICPC”,”abc”,”kkkkk”}; sort(a,a+N); sort(str,str+N); return 0; }
2.从大到小排序(需要自己写comp函数) const int N = 5; int cmp(int a,int b) {return a > b;} int main() { int a[N] = {4,3,2,6,1}; sort(a,a+N,cmp); return 0;}
3. 对结构体排序 struct SS {int first,second;}; int cmp(SS a,SS b) { if (a.first != b.first) return a.first < b.first; return a.second < b.second; } v.s. qsort() in C (平均情况O(nlogn),最坏情况O(n^2)) int cmp(const void *a,const void *b) { if (((SS*)a)->first != ((SS*)b)->first) return ((SS*)a)->first – ((SS*)b)->first; return ((SS*)a)->second – ((SS*)b)->second; } qsort(array,n,sizeof(array[0]),cmp);
sort()系列: stable_sort(first,last,cmp); //稳定排序 partial_sort(first,middle,last,cmp);//部分排序 将前(middle-first)个元素放在[first,middle)中,其余元素位置不定 e.g. int A[12] = {7, 2, 6, 11, 9, 3, 12, 10, 8, 4, 1, 5}; partial_sort(A, A + 5, A + 12); // 结果是 "1 2 3 4 5 11 12 10 9 8 7 6". Detail: Heapsort , O((last-first)*log(middle-first))
sort()系列: partial_sort_copy(first, last, result_first, result_last, cmp); //输入到另一个容器,不破坏原有序列 bool is_sorted(first, last, cmp); //判断是否已经有序 nth_element(first, nth, last, cmp); //使[first,nth)的元素不大于[nth,last), O(N) e.g. input: 7, 2, 6, 11, 9, 3, 12, 10, 8, 4, 1, 5 nth_element(A,A+6,A+12); Output: 5 2 6 1 4 3 7 8 9 10 11 12
<algorithm> 2. binary_search() bool binary_search(ForwardIterator first, ForwardIterator last, const LessThanComparable& value); bool binary_search(ForwardIterator first, ForwardIterator last, const T& value, StrictWeakOrdering comp); 在[first,last)中查找value,如果找到返回Ture,否则返回False 二分检索,复杂度O(log(last-first)) v.s. bsearch() in C
Binary_search()系列 itr upper_bound(first, last, value, cmp); //itr指向大于value的第一个值(或容器末尾) itr lower_bound(first, last, value, cmp); //itr指向不小于valude的第一个值(或容器末尾) pair<itr,itr> equal_range(first, last, value, cmp); //找出等于value的值的范围 O(2*log(last – first)) int A[N] = {1,2,3,3,3,5,8} *upper_bound(A,A+N,3) == 5 *lower_bound(A,A+N,3) == 3
<algorithm> make_heap(first,last,cmp) O(n) push_heap(first,last,cmp) O(logn) pop_heap(first,last,cmp) O(logn) is_heap(first,last,cmp) O(n) e.g: vector <int> vi; while (scanf(“%d”,&n) != EOF) { vi.push_back(n); push_heap(vi.begin(),vi.end()); }
<algorithm> Others interesting: next_permutation(first, last, cmp) prev_permutation(first, last, cmp) //both O(N) min(a,b); max(a,b); min_element(first, last, cmp); max_element(first, last, cmp);
<algorithm> Others interesting: fill(first, last, value) reverse(first, last) rotate(first,middle,last); itr unique(first, last); //返回指针指向合并后的末尾处 random_shuffle(first, last, rand)
Some others… More container: Rope, Slist, Bitset … More about iterator Memory allocation Function object …
SGI STL: http://www.sgi.com/tech/stl/ STL China : http://www.stlchina.org/ <<Effective STL>> : http://www.stlchina.org/documents/EffectiveSTL/index.html Topcoder: http://www.topcoder.com/tc