# Week 1: Array; Sorting; C++ Specifics [ToC] ## Declare large arrays globally instead of locally - This is **bad**: ```cpp= void some_func() { ... int b[200000]; // array local to `some_func`, may fail allocation due to large size ... } int main() { ... int a[100000]; // array local to `main`, may fail allocation due to large size ... some_func(); ... } ``` - This is **good**: ```cpp= int a[100000], b[200000]; // global now; allocation won't fail void some_func() { ... } int main() { ... some_func(); ... } ``` - The reason is not important for us, but *if you're curious*: A local data uses the stack allocation strategy which allows for a limited amount of data to be allocated. On the other hand, a global data is allocated statically on a separate data segment where the only limit is the available size of the RAM. ## `vector`: Dynamic array in C++ STL - An array that can grow/shrink at the back efficiently at runtime. - Will be your most often used data sructure. ### How to use - Declare: ```cpp= // type of the contained element goes inside `<` and `>` vector<int> a; vector<double> b; vector<string> c; ``` - Declare with pre-allocated size and fill-value: ```cpp= vector<int> a1(1000); // 1000 ints, all set to 0 (the default int value) vector<string> b1(1000); // 1000 strings, all set to "" (the default string value) vector<int> a2(1000, -1); // 1000 ints, all set to -1 vector<string> b2(1000, "xyz"); // 1000 strings, all set to "xyz" ``` - Query size/length in $O(1)$ time: ```cpp= a.size(); a.empty(); // returns `a.size() == 0` ``` - Index-based access to elements in $O(1)$ time, like in arrays: ```cpp= cout << "first element: " << a[0] << "\n"; cout << "last element: " << a[a.size() - 1] << "\n"; ... cout << "all elements: "; for (int i = 0; i < a.size(); i++) { cout << a[i] << " "; } cout << "\n"; a.front(); // convenience function to access first element without index a.back(); // convenience function to access last element without index ``` - **[Most important]** Add/remove elements **at the back** in $O(1)+$ (i.e. amortized constant) time: ```cpp= vector<int> a; for (int i = 0; i < 10; i++) { a.push_back(i + 1); cout << "added: " << a.back() << "\n"; } for (int i = 0; i < 10; i++) { cout << "removing: " << a.back() << "\n"; a.pop_back(); } ``` ### When and why to use - You don't know the number of elements beforehand ## `deque`: Dynamic array, but for both ends - Exactly like `vector`, but can also add/remove **at the front**: ```cpp= deque<int> a; for (int i = 0; i < 10; i++) { if (i % 2 == 0) { a.push_front(i); } else { a.push_back(i); } } for (int i = 0; i < 10; i++) { cout << a[i] << " "; } cout << "\n"; ```