ENS Lyon Camp. Day 5. Basic group. C++. 30 October Contents 1 Input/Output 1 1.1 C-style.......................................... 1 1. C++-style........................................ Stack Overflow Runtime Error 3 STL containers 3.1 Pair........................................... 3. Vector.......................................... 3 3.3 Queue.......................................... 4 3.4 Deque.......................................... 4 3.5 Set............................................ 5 3.6 Map........................................... 7 4 STL sort 8 1 Input/Output 1.1 C-style 1 #i n c l u d e <s t d i o. h> 3 i n t main ( ) 4 { 5 i n t a ; 6 FILE * f i n, * f o u t ; 7 f i n = fopen ( " example. in ", " r " ) ; 8 f o u t = fopen ( " example. out ", "w" ) ; f s c a n f ( f i n, "%i ", &a ) ; 10 f p r i n t f ( fout, "%i ", a ) ; 11 f c l o s e ( f i n ) ; 1 f c l o s e ( f o u t ) ; 13 } There is an issue with long long variables. You should use specifier "%I64d" for Windows and specifier "%lld" for all other operating systems. To prevent errors with this issue you could define the following macros: 1
1 #i f d e f WIN3 p r i n t f ( "%I64d \n", ans ) ; 3 #e l s e 4 p r i n t f ( "%l l d \n", ans ) ; 5 #e n d i f 1. C++-style Another possibility to avoid this issue is usage of C++. 1 #i n c l u d e <fstream> 3 i n t main ( ) 4 { 5 long a ; 6 i f s t r e a m f i n ( " example. in " ) ; 7 ofstream f o u t ( " example. out " ) ; 8 f i n >> a ; f o u t << a << endl ; 10 f i n. c l o s e ( ) ; 11 f o u t. c l o s e ( ) ; 1 } Stack Overflow Runtime Error All variables store in two different places in the memory. One of it is called stack and another one is called heap (In this context there is no connection between them and data structures with the same names). Heap is a region of memory that stores all global variables, memory that allocates using new(), malloc(), etc. functions. Stack is a special region of memory that stores temporary variables created by each function (including the main() function). Stack variables only exist while the function that created them, is running. You should keep in mind, that there is a limit (varies with OS) on the size of variables that can be store on the stack. So if you declare large array in the main function, you program crash. If you have a lot of recursive calls, you program crash. You can set size of stack manually as follows: #pragma comment(linker, "/STACK:3677716"). The size is specified in bytes. 3 STL containers 3.1 Pair This class couples together a pair of values, which may be of different types. 1 #i n c l u d e <u t i l i t y > // std : : p a i r 3 i n t main ( ) { 4 // d e c l a r a t i o n 5 std : : p a i r <int, double> p ;
6 7 // c r e a t e p a i r 8 p = std : : make_pair ( 1 0, 3. 1 4 1 5 ) ; 10 // output f i r s t and second elements o f p a i r 11 std : : cout << p. f i r s t << ", " << p. second << \n ; 1 } 3. Vector Vectors represent arrays that can change in size. Vectors are very efficient accessing its elements (just like arrays) and relatively efficient adding or removing elements from its end. You can create vectors with the following constructors: 1 #i n c l u d e <vector > 3 i n t main ( ) 4 { 5 std : : vector <int > f i r s t ; // empty v e c t o r o f i n t s 6 std : : vector <int > second ( 4, 1 0 0 ) ; // f o u r i n t s with value 100 7 std : : vector <int > t h i r d ( second. begin ( ), second. end ( ) ) ; // i t e r a t i n g second 8 std : : vector <int > f o u r t h ( t h i r d ) ; // a copy o f t h i r d 10 i n t myints [ ] = { 1 6,, 7 7, } ; 11 std : : vector <int > f i f t h ( myints, myints + s i z e o f ( myints ) / s i z e o f ( i n t ) ) ; 1 } Here is the examples of vector usage: 1 i n t main ( ) { 3 std : : vector <int > v ; 4 5 // Returns whether the v e c t o r i s empty 6 bool isempty = v. empty ( ) ; 7 8 // Returns the number o f elements in the v e c t o r. i n t s i z e = v. s i z e ( ) ; 10 11 // Adds a new element at the end o f the vector, a f t e r i t s c u r r e n t l a s t element. 1 v. push_back ( 5 ) ; 13 14 // Removes the l a s t element in the v e c t o r. 15 v. pop_back ( ) ; 16 17 // Returns a r e f e r e n c e to the f i r s t element in the v e c t o r. 18 i n t f i r s t = v. f r o n t ( ) ; 1 0 // Returns a r e f e r e n c e to the l a s t element in the v e c t o r. 1 i n t l a s t = v. back ( ) ; 3 // Returns a r e f e r e n c e to the element at p o s i t i o n i in the v e c t o r c o n t a i n e r. 3
4 i n t x = v [ i ] ; 5 } Time complexity of all operation is O(1). 3.3 Queue Queues operates in a FIFO context (first-in first-out), where elements are inserted into one end of the container and extracted from the other. You can create it in the same way as vector. Here is the examples of queue usage: 1 #i n c l u d e <queue> i n t main ( ) 3 { 4 std : : queue<int > q ; 5 6 // Adds a new element at the end o f the queue, a f t e r i t s c u r r e n t l a s t element. 7 q. push ( 5 ) ; 8 // Remove the " o l d e s t " element in the queue 10 q. pop ( ) ; 11 1 // Returns whether t h e queue i s empty 13 bool isempty = q. empty ( ) ; 14 15 // Returns the number o f elements in the queue 16 i n t s i z e = q. s i z e ( ) ; 17 18 // Returns a r e f e r e n c e " o l d e s t " element in the queue 1 i n t f i r s t = q. f r o n t ( ) ; 0 1 // Returns a r e f e r e n c e to the the " newest " element in the queue i n t l a s t = q. back ( ) ; 3 } 4 3.4 Deque Deque is a double-ended queue. Double-ended queues are sequence containers with dynamic sizes that can be expanded or contracted on both ends (either its front or its back). It constructs in the same way. Here is the examples of deque usage: 1 #i n c l u d e <deque> i n t main ( ) 3 { 4 std : : deque<int > q ; 5 6 // Returns whether t h e queue i s empty 7 bool isempty = q. empty ( ) ; 8 4
// Returns the number o f elements in the queue 10 i n t s i z e = q. s i z e ( ) ; 11 1 // Adds a new element at the end o f the deque c o n t a i n e r 13 q. push_back ( 5 ) ; 14 15 // Removes the l a s t element in the deque 16 q. pop_back ( ) ; 17 18 // I n s e r t s a new element at the beginning o f the deque 1 q. push_front ( ) ; 0 1 // Removes the f i r s t element in the deque q. pop_front ( ) ; 3 4 // Returns a r e f e r e n c e to the f i r s t element in the deque 5 i n t f i r s t = q. f r o n t ( ) ; 6 7 // Returns a r e f e r e n c e to the l a s t element in the c o n t a i n e r. 8 i n t l a s t = q. back ( ) ; 30 // Returns a r e f e r e n c e to the element at p o s i t i o n i in the deque. 31 i n t x = v [ i ] ; 3 } 33 3.5 Set Sets are containers that store unique elements following a specific order (elements must be comparable). Set implementation uses binary search trees. There is two way to redefine comparator of elements 1 bool cmpfunction ( i n t l, i n t r ) { return r < l ; } 3 s t r u c t cmpclass { 4 bool o perator ( ) ( const i n t& l, const i n t& r ) const 5 { return r < l ; } 6 } ; 7 8 i n t main ( ) { 10 std : : set <int > f i r s t ; // empty s e t o f i n t s 11 1 i n t myints []= { 1 0, 0, 3 0, 4 0, 5 0 } ; 13 std : : set <int > second ( myints, myints+5) ; // range 14 15 std : : set <int > t h i r d ( second ) ; // a copy o f second 16 17 std : : set <int > f o u r t h ( second. begin ( ), second. end ( ) ) ; // i t e r a t o r 18 1 std : : set <int, cmpclass> f i f t h ; // r e d e f i n e comparator using c l a s s 5
0 1 bool (* fn_pt ) ( int, i n t ) = cmpfunction ; // d e c l a t e p o i n t e r to cmpfunction std : : set <int, bool ( * ) ( int, i n t )> s i x t h ( fn_pt ) ; // r e d e f i n e comparator 3 } 4 Here is the examples of set usage: 1 i n t main ( ) { 3 std : : set <int > s ; 4 5 // Returns whether the s e t i s empty 6 bool isempty = s. empty ( ) ; 7 8 // Returns the number o f elements in the queue i n t s i z e = s. s i z e ( ) ; 10 11 // Returns a pair, with i t s member p a i r : : f i r s t s e t to an i t e r a t o r 1 // p o i n t i n g to e i t h e r the newly i n s e r t e d element 13 // or to the e q u i v a l e n t element already in the s e t. 14 // The p a i r : : second element in the p a i r i s s e t to true i f a new element 15 // was i n s e r t e d or f a l s e i f an e q u i v a l e n t element a lready e x i s t e d. 16 s. i n s e r t ( 0) ; 17 18 i n t a []= { 5, 1 0, 1 5 } ; 1 s. i n s e r t ( myints, myints+3) ; 0 1 // Removes from the s e t c o n t a i n e r e i t h e r a s i n g l e element // or a range o f elements ( [ f i r s t, l a s t ) ). 3 i t = s. begin ( ) ; 4 s. e r a s e ( i t ) ; // e r a s i n g by value 5 s. e r a s e (0) ; // e r a s i n g by key 6 7 // Searches the c o n t a i n e r f o r an element e q u i v a l e n t to val and r e t u r n s 8 // an i t e r a t o r to i t i f found, o t h e r w i s e i t r e t u r n s an i t e r a t o r to s e t : : end. s. f i n d (0) ; 30 31 // Returns an i t e r a t o r p o i n t i n g to the f i r s t element in the c o n t a i n e r 3 // which i s not c o n s i d e r e d to go b e f o r e val 33 // ( i. e., e i t h e r i t i s e q u i v a l e n t or goes a f t e r ). 34 std : : set <int >:: i t e r a t o r lb = s. lower_bound (0) ; 35 36 // Returns an i t e r a t o r p o i n t i n g to the f i r s t element in the c o n t a i n e r 37 // which i s c o n s i d e r e d to go a f t e r val. 38 std : : set <int >:: i t e r a t o r ub = s. upper_bound (0) ; 3 } 40 There is similar container multiset, that allows store the equivalent values with the same methods; 1 #i n c l u d e <set > 3 typedef std : : multiset <int >:: i t e r a t o r s e t I t ; 6
4 5 i n t main ( ) 6 { 7 std : : multiset <int > s ; 8 // Count elements with a s p e c i f i c key 10 i n t cnt = s. count (4) ; 11 1 // Get range o f equal elements 13 std : : pair <s e t I t, s e t I t > r e t = mymultiset. equal_range (4) ; 14 } 15 Time complexity is O(log n). In C++11 there exists unordered set (hash set), that stores unordered value and time complexity is approximately O(1) (#include <unordered_set>). 3.6 Map Maps are associative containers that store elements formed by a combination of a key value and a mapped value, following a specific order. You can redefined compare operator in the same way as it was redefined in set. Here is example of usage map. 1 #i n c l u d e <map> 3 i n t main ( ) 4 { 5 std : : map<char, int > m; 6 7 // Returns whether t h e map i s empty 8 bool isempty = m. empty ( ) ; 10 // Returns the number o f elements in the map 11 i n t s i z e = m. s i z e ( ) ; 1 13 // Returns a pair, with i t s member p a i r : : f i r s t s e t to an i t e r a t o r p o i n t i n g 14 // to e i t h e r the newly i n s e r t e d element 15 // or to the e q u i v a l e n t element already in the map. 16 // The p a i r : : second element in the p a i r i s s e t to true 17 // i f a new element was i n s e r t e d 18 // or f a l s e i f an e q u i v a l e n t element already e x i s t e d. 1 m. i n s e r t ( std : : pair <char, int >( a,100) ) ; 0 1 // Removes from the map c o n t a i n e r e i t h e r a s i n g l e element // or a range o f elements ( [ f i r s t, l a s t ) ). 3 i t = m. begin ( ) ; 4 m. e r a s e ( i t ) ; // e r a s i n g by i t e r a t o r 5 s. e r a s e ( a ) ; // e r a s i n g by key 6 7 // Searches the c o n t a i n e r f o r an element e q u i v a l e n t to val 8 // and r e t u r n s an i t e r a t o r to i t i f found, // o t h e r w i s e i t r e t u r n s an i t e r a t o r to map : : end. 7
30 s. f i n d ( a ) ; 31 3 // Returns an i t e r a t o r p o i n t i n g to the f i r s t element in the c o n t a i n e r 33 // which i s not c o n s i d e r e d to go b e f o r e val 34 std : : map<char, int >:: i t e r a t o r lb = m. lower_bound ( a ) ; 35 36 // Returns an i t e r a t o r p o i n t i n g to the f i r s t element in the c o n t a i n e r 37 // which i s c o n s i d e r e d to go a f t e r val. 38 std : : map<char, int >:: i t e r a t o r ub = m. upper_bound ( b ) ; 3 40 // I f k matches the key o f an element in the container, 41 // the f u n c t i o n r e t u r n s a r e f e r e n c e to i t s mapped value. 4 // I f k does not match the key o f any element in the container, 43 // the f u n c t i o n i n s e r t s a new element with that key 44 // and r e t u r n s a r e f e r e n c e to i t s mapped value. 45 mymap[ a ] = 5 ; 46 } 47 Similary there exists multimap that allows store the equivalent values with the same methods; In C++11 there exists unordered map (hash map) that stores unordered value and time complexity is approximately O(1) (#include <unordered_map>). 4 STL sort 1 #i n c l u d e <algorithm > // std : : s o r t #i n c l u d e <vector > 3 4 bool cmpfunction ( i n t l, i n t r ) { return ( r < l ) ; } 5 6 s t r u c t cmpclass { 7 bool o perator ( ) ( i n t l, i n t r ) { return ( r < l ) ; } 8 } myobject ; 10 i n t main ( ) { 11 i n t myints [ ] = { 3, 7 1, 1, 4 5, 6, 8 0, 5 3, 3 3 } ; 1 std : : vector <int > myvector ( myints, myints+8) ; 13 14 // using d e f a u l t comparison ( operator <) : 15 std : : s o r t ( myvector. begin ( ), myvector. begin ( ) +4) ; 16 17 // using f u n c t i o n as comp 18 std : : s o r t ( myvector. begin ( ) +4, myvector. end ( ), myfunction ) ; 1 0 // using o b j e c t as comp 1 std : : s o r t ( myvector. begin ( ), myvector. end ( ), myobject ) ; } 3 8
There is function std :: stable_sort that preserves the relative order of the elements with equivalent values.