# 黑魔法 ## 資料流 ### Intro ```cpp= #include <iostream> ``` 回過頭來看看這行 這什麼東西? $\text{iostream}$ 為 $\text{Input/Output Stream}$ 的縮寫,即是輸入/輸出流。 「流」是一連串從 $\text{I/O}$ 裝置讀寫的字元。($\text{From Wiki}$) $\text{iostream}$ 分成 $\text{istream}$ 和 $\text{ostream}$ 但今天重點不是這個 ### stringstream 用處: 整行輸入時能拿來用 ```cpp= #include <sstream> using namespace std; int main() { string tmp; stringstream ss; getline(cin, tmp); ss << tmp; vector<int> v; int a; while (ss >> a) { v.push_back(a); } return 0; } ``` 也許有更精簡的寫法 ### fstream 讀/寫檔 ```cpp= ifstream fin; fin.open("input.txt"); vector<int> v(10); for (int i = 0; i < 10; i++) { fin >> v[i]; } ofstream fout("out.txt"); for (int i = 9; i >= 0; i--) { fout << v[i] << endl; } fin.close(); fout.close(); ``` 拿來生測資 非常好 ## using 有三種用法 但這裡只介紹兩種 ### using namespace ```cpp= #include <bits/stdc++.h> struct node { int value; node *ln, *rn; }; void swap(node &x) { using std::swap; swap(x->ln, x->rn); return; } int main() { using std::string; string s; std::cout << s << endl; } ``` ### as typedef ```cpp= #define LL long long typedef long long LL; using LL = long long; ``` ## max/min ```cpp= cout << max({1, 2, 3, 4, 5}) << endl; cout << min({1, 2, 3, 4, 5}) << endl; ``` ## reference 就是別名 ```cpp= string s; string &ref = s; ``` 此時 $\text{ref = s}$ ```cpp=+ s = "Hi"; cout << ref << endl; ref += "Yes"; cout << s << endl; cout << ref << endl; ``` ```cpp= #include <bits/stdc++.h> using namespace std; void Add_B(string &ref) { ref += "B"; return; } int main() { string s = "AAA"; Add_B(s); cout << s << endl; return 0; } ``` ## 在 if 裡面宣告變數 ```cpp= set<LL> s; if (auto it = s.find(10); it != s.end()) { cout << *it << endl; } ``` ## 關於字串... 懶得用跳脫字元? ```cpp= string s = R"(\n"'""')"; string a = "\\n\"'\"\"'"; cout << s << endl; cout << a << endl; ``` 執行結果: ``` \n"'""' \n"'""' ``` ## decltype ```cpp= int a = 10; auto b = 10; // b is an interger decltype(b) c; // c is an interger priority_queue<int> pq; decltype(pq) pq2; ``` 釋放空間 ```cpp= #include <bits/stdc++.h> using namespace std; vector<int> v; void reset() { decltype(v)().swap(v); } int main() { return 0; } ``` ## 傳入多個參數 ```cpp= template <typename T> void ls(T &v) { for (auto i : v) cout << i << " "; cout << endl; } template <typename T, typename... Args> void ls(T &v, const Args &...args) { for (auto i : v) cout << i << " "; cout << endl; ls(args...); } int main() { vector<int> a, b; set<int> s1, s2; ls(a, b, s1, s2); return 0; } ``` ## 隨機數 ```cpp= mt19937 rng(time(NULL)); for (int i = 0; i < 10; i++) { cout << rng() << endl; } ``` [**梅森旋轉算法**](https://zh.wikipedia.org/zh-tw/%E6%A2%85%E6%A3%AE%E6%97%8B%E8%BD%AC%E7%AE%97%E6%B3%95) ## 三元運算 ```cpp= bool f = false; int a; cin >> a; if (a & 1) { f = true; } cout << (f == true ? "odd" : "even") << endl; ``` ```cpp= x = (y < 0) ? 1 : 2; // if y < 0, x = 1; else x = 2 (c < 0 ? a : b) = 1; // if c < 0, a = 1; else b = 1 ``` ## 這標題該怎麼下 ```cpp= cout << "ABCD"[2] << endl; ``` ```cpp= int n; vector<int> v(n, 10); for (int i = 0; i < n; i++) { cout << v[i] << " \n"[i == n - 1]; } ``` ## switch [**A. Division?**](https://codeforces.com/problemset/problem/1669/A) ```cpp= void sol() { LL n; cin >> n; cout << "Division "; switch (n) { case -5000 ... 1399: cout << 4 << endl; break; case 1400 ... 1599: cout << 3 << endl; break; case 1600 ... 1899: cout << 2 << endl; break; default: cout << 1 << endl; } } ``` ## define for debug ```cpp= #include <bits/stdc++.h> using namespace std; #define ch cout << "Hi" << endl int main() { ch; return 0; } ``` ```cpp= #include <bits/stdc++.h> using namespace std; #define ch cout << "Hi at line" << __LINE__ << endl int main() { ch; ch; ch; return 0; } ``` ```cpp= #include <bits/stdc++.h> using namespace std; #define ch(x) cout << #x << ": " << x << endl int main() { int a = 10; ch(a); return 0; } ``` [**宏定义的黑魔法 - 宏菜鸟起飞手册**](https://onevcat.com/2014/01/black-magic-in-macro/) ## 蝌蚪(?) ```cpp= int x = 5; cout << ~-x << endl; cout << -~x << endl; cout << x << endl; ``` ## 沒了 ![alt image](https://i.imgur.com/WB7vDIz.png)