# Learning knowledge ###### tags: `Study_aboard` ## STL https://www.geeksforgeeks.org/the-c-standard-template-library-stl/ STL can help implement data structures more easily ### Vector ```cpp vector<> v(size, val) // Initialize vector<> v({element}) // Initialize vector.push_back // time complexity O(1) vector.insert(position(iterator), val) // time complexity O(N) sort(vector.begin(), vector.end()) vector<>::iterator it = find(vector.begin(), vector.end()) // it==vector.end() if not found vector.clear() // clean the vector ``` ### Unordered_map (HashMap) Timing: $O(1)$ access time ```cpp unordered_map<Key,T> m; unordered_map<int,int> second = {{1,10},{2,20},{3,30}};// initialize m->first // the key value m->second // the mapped value m.count(key) // find with a specific key, =0 if not found m.erase ( m.begin() ); // erase by iterator m.erase(m.begin()+3, m.end() ) // erase by a range of iterator m.clear() ``` ### Queue (BFS) ```cpp queue<> q // Initialzie q.front() // the top of a queue q.pop() // pop out top element q.push() // push to the end of the queue ``` ### Priority Queue (Heap) https://sites.google.com/site/zsgititit/home/jin-jiec-cheng-shi-she-ji/stl/priority https://www.geeksforgeeks.org/priority-queue-in-cpp-stl/ 優先隊列,資料預設由大到小排序,大的資料會先被取出 - push - top - auto - size ```cpp template <class T, class Container = vector<T>, class Compare = less<typename Container::value_type> > class priority_queue; ``` Can define cmp by yourself ```cpp example: // use priority queue to implement min heap auto cmp = [](ListNode*& a, ListNode*& b) { return (a->val>b->val); }; priority_queue<ListNode*, vector<ListNode*>, decltype(cmp) > q(cmp); //有時候難以得知一些物件的type,此時就可以透過auto或decltype來解決這個問題。 ``` ### Doubled linked list [More Linked list stl](https://www.geeksforgeeks.org/list-cpp-stl/) Timing: $O(1)$ remove time and add time But hard to access it and uses extra memories ```cpp list<pair<int, int>> l; // initialize l.front() l.back() l.push_front(pair<int,int>) // push to the front l.push_back(pair<int,int>) // push to the back l.pop_front() l.pop_back() list<pair<int, int>>::iterator l.begin(),l.end(), l.rbegin(),l.rend() l.reverse() // reverse the linked list l.clear() // clean the linked list l.splice /* * * The splice() function can be used in three ways: 1.Transfer all the elements of list x into another list at some position. 2.Transfer only the element pointed by i from list x into the list at some position. 3.Transfers the range [first, last) from list x into another list at some position. */ list1_name.splice (iterator position, list2) or list1_name.splice (iterator position, list2, iterator i) or list1_name.splice (iterator position, list2, iterator first, iterator last) ``` ### Iterator Iterators are something which is used to point at the memory addresses of STL containers’ elements. Thus providing a means to access the data stored within the container and ability to modify them. They can be simply thought of as pointers. **Syntax : container <data-type> :: iterator iterator_name;** example: ```cpp vector<int>::iterator it; ``` **Syntax : container <data-type> :: reverse_iterator iterator_name;** example: ```cpp vector<int>::reverse_iterator it; ``` ![](https://i.imgur.com/zlYF8QB.png) ```cpp it = v.begin() it = v.end() it= v.rbegin() it = v.rend() /* The r means reverse container begin, rbegin ++ end, rend -- */ example for(it=vector.rbegin();it!=vector.rend();it++) //this will iterate the vector by reverse order ``` ### Auto auto : x (vector) -> can iterate through x for(auto : x) auto 可用於自動判定變數的聲明 ex: auto x = 1 -> equal to int x = 1 [auto reference](https://blog.gtwang.org/programming/cpp-auto-variable-tutorial/) ## Algorithm ### ==Divide and conquer== 1. divide problem into small problem and make sure they can obtain the same rule 2. conqure (recursively sovle the small problem) 3. merge small problem into the final answer [reference](https://medium.com/brandons-computer-science-notes/divide-and-conquer-algorithms-4e83d9999ffa) ### ==Dynamic Programming== Divide and conquer will generate same subproblems. To avoid extraneous computing, we have to remember the subproblem that we had done before, which is dynamic program. ![](https://i.imgur.com/eEOvyKR.png) #### Top-down or bottom up Take fabonacci sequence as an example F(n) = F(n-1) + F(n-2) top-down : plus an memo array to remember things that had finish computing ```cpp memo = {} def fibonacci(n): if n == 0 or n == 1: return n else: if n in memo: return memo[n] else: memo[n] = fibonacci(n - 1) + fibonacci(n - 2) return memo[n] ``` bottom-up : add from F(1) to F(2) to F(1000) ```cpp def fibonacci(n): if n == 0 or n == 1: return n dp = [None for _ in range(n + 1)] dp[0] = 0 dp[1] = 1 for i in range(2, n + 1): dp[i] = dp[i-1] + dp[i-2] return dp[n] ``` [reference](https://medium.com/@ryanyang1221/dynamic-programming-explanation-with-fibonacci-%E7%94%A8%E8%B2%BB%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B8%E5%88%97%E4%BE%86%E8%A7%A3%E9%87%8B%E5%8B%95%E6%85%8B%E8%A6%8F%E5%8A%83-8ce318601d0f) ### ==Binary search== Timing : To search a sorted array Complexity : $log{_2}{N}$ Specify left, right, mid, compare mid with the target and change right or left continuously (夾擊法) ![](https://i.imgur.com/O1vWxH6.png) [C++ code implementation](https://hackmd.io/@chentzj/S1efSWY0d#Binary-search-algorithm) ### ==KMP Algorithm== https://binary-baba.medium.com/string-matching-kmp-algorithm-27c182efa387 https://www.youtube.com/watch?v=BXCEFAzhxGY&t=881s objection: 加速尋找 substring p 在 string s 的位置 example: s = adsgwadsxdsgwadsg , p = dsgwadsg prefix: 從第一位開始的一串substring suffix: 包含最後一位的substring 主要加速方法是當mismatch時,檢查match的字串中是否有prefix=suffix的可能,若有則可以從suffix開始做下一次的比較 檢查的方式是建立一個prefix, suffix table table[i] : 1. 表 string 0~i suffix==prefix的長度 2. the repeated char's position example: table[5] = dsgwad 's longest length of suffix and prefix = 1 三種可能情形,可見code ==若比對不相等 W[i]!= W[j],從前一個相等的char的prefix來找== [C++ code implement](https://hackmd.io/@chentzj/H1BHDRPfu#Implement-strStr) ### ==Topological sort== Timing: Sorting orders for strange order things Topological sort is only for DAG (directed acyclic graph). For every edge u->v, we out put node u before v For Example: ![](https://i.imgur.com/4eQxad8.png) 405231 is a valid output, but 450231 is not Topological sort can be implement by two ways, modified BFS and modified DFS #### Modified DFS ![](https://i.imgur.com/mgfwJTt.png) The output order is decided by the number of outgoing edges. We start from nodes that do not have outgoing edges (0,1 in this case) Therefore, we start from nodes with the least outgoing edges, and we do recursive to its outgoing edges and output them before the node. An additional stl to record nodes that are visited already, so that we do not output same nodes again. ```cpp // A C++ program to print topological // sorting of a DAG #include <iostream> #include <list> #include <stack> using namespace std; // Class to represent a graph class Graph { // No. of vertices' int V; // Pointer to an array containing adjacency listsList list<int>* adj; // A function used by topologicalSort void topologicalSortUtil(int v, bool visited[], stack<int>& Stack); public: // Constructor Graph(int V); // function to add an edge to graph void addEdge(int v, int w); // prints a Topological Sort of // the complete graph void topologicalSort(); }; Graph::Graph(int V) { this->V = V; adj = new list<int>[V]; } void Graph::addEdge(int v, int w) { // Add w to v’s list. adj[v].push_back(w); } // A recursive function used by topologicalSort void Graph::topologicalSortUtil(int v, bool visited[], stack<int>& Stack) { // Mark the current node as visited. visited[v] = true; // Recur for all the vertices // adjacent to this vertex list<int>::iterator i; for (i = adj[v].begin(); i != adj[v].end(); ++i) if (!visited[*i]) topologicalSortUtil(*i, visited, Stack); // Push current vertex to stack // which stores result Stack.push(v); } // The function to do Topological Sort. // It uses recursive topologicalSortUtil() void Graph::topologicalSort() { stack<int> Stack; // Mark all the vertices as not visited bool* visited = new bool[V]; for (int i = 0; i < V; i++) visited[i] = false; // Call the recursive helper function // to store Topological // Sort starting from all // vertices one by one for (int i = 0; i < V; i++) if (visited[i] == false) topologicalSortUtil(i, visited, Stack); // Print contents of stack while (Stack.empty() == false) { cout << Stack.top() << " "; Stack.pop(); } } // Driver Code int main() { // Create a graph given in the above diagram Graph g(6); g.addEdge(5, 2); g.addEdge(5, 0); g.addEdge(4, 0); g.addEdge(4, 1); g.addEdge(2, 3); g.addEdge(3, 1); cout << "Following is a Topological Sort of the given " "graph \n"; // Function Call g.topologicalSort(); return 0; } ``` ![](https://i.imgur.com/gkgVzfE.png)