输入输出
cin
的结束符是空格, 制表符和回车,
读完后结束符仍然在缓冲区. getline
的结束符是回车,
读完后结束符不在缓冲区.
读取一行有空格字符串需要getline
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 int n;cin >> n; cin.ignore (); vector<string> s (n) ;for (int i = 0 ; i < n; ++i) { getline (cin, s[i]); } string input; getline (cin, input);input.erase (remove (input.begin (), input.end (), '\r' ), input.end ()); input.erase (remove (input.begin (), input.end (), '\t' ), input.end ()); input.erase (remove (input.begin (), input.end (), '\n' ), input.end ());
将空格分隔的字符串读到vector
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 vector<string> split (string input) { vector<string> res; istringstream ss (input) ; string tmp; while (ss >> tmp) { res.push_back (tmp); } return res; } vector<string> split (const string &str) { vector<string> tokens; string::size_type start = 0 , end = 0 ; while ((end = str.find (" " , start)) != string::npos) { tokens.push_back (str.substr (start, end - start)); start = end + 1 ; } tokens.push_back (str.substr (start)); return tokens; } vector<string> split (string input) { vector<string> res; istringstream ss (input) ; string tmp; while (getline (ss, tmp, ',' )) { res.push_back (tmp); } return res; }
知道数组大小后,可以直接读到数组中
1 2 3 4 vector<int > nums (n) ;for (int i = 0 ; i < n; ++i) { cin >> nums[i]; }
删除首尾空格
1 2 s.erase (s.find_last_not_of (" " ) + 1 ); s.erase (0 , s.find_first_not_of (" " ));
多个数最大/最小
1 2 min ({a, b, c, d, e});*max_element (nums.begin (), nums.end ());
STL总结
int stoi(const string& str, size_t* idx=0, int base=10)
:idx
指向第一个非数字字符
isalpha(int ch)
: 头文件cctype
对map
或unordered_map
按值排序
1 2 3 4 5 6 7 8 unordered_map<string, int > record{{"a" , 2 }, {"b" , 1 }}; vector<pair<string, int >> vec (record.begin (), record.end ()); std::sort (vec.begin (), vec.end (), [](const pair<string, int >& a, const pair<string, int >& b) {return a.second < b.second;}); for (auto it = vec.begin (); it != vec.end (); ++it) { cout << it->first << " " ; }
unordered_map
自定义key
unordered_map<pair<int, int>, int>
会报错,需要提供一个hash函数.
如果key不存在,访问仍然成功,返回value对象默认构造值
1 2 3 4 5 6 7 8 9 struct PairHash { template <typename T, typename U> size_t operator () (const pair<T, U> &x) const { auto h1 = hash<T>()(x.first), h2 = hash<U>()(x.second); return h1 ^ h2; } }; unordered_map<pair<int , int >, int , PairHash> m;
但是`map`就不需要, map的key类型必须支持`<`运算符
sort(v.begin(), v.end(), [](int a, int b) { return a > b; })
或sort(v.rbegin(), v.rend())
vector追加:
dest.insert(dest.end(), src.begin(), src.end())
.
vector<vector<int>>
每一维元素个数可以不同
C++ 17的structured binding:
for (auto [k, v] : unordered_map)
std::lower_bound
和std::upper_bound
对于random-access
iterators的时间复杂度是\(O(lgn)\) ,但对于non-random-access
iterators如set::iterator
是\(O(n)\) 的。这种情况下应使用set
自带的setObj.upper_bound(target)
,复杂度\(O(lgn)\)
反向迭代:for (auto it = nums.rbegin(); it != nums.rend(); ++it)
sort
记录原始索引:可以先过一遍数组,将数字和索引绑定,然后对pair
排序。
string(10, 'x')
string res; res += string(10, 'x');
常见算法:
1. 二分答案
2. 数组、哈希表、优先队列、栈、双向队列(在头尾都操作的)
3. 深搜:建图转化
4. 排序
5. 贪心: 从大到小/从小到大排序、单位价值排序
6. 拓扑排序
7. 并查集
8. DP:线性、二维、背包
9. 双指针:对撞、快慢、滑动窗口
10. 模拟
11. 数学:猜答案、打表
12. 前缀和、差分
知识点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 vector<int > preSum (n + 1 , 0 ) ;for (int i = 1 ; i <= n; ++i) { preSum[i] = preSum[i - 1 ] + nums[i - 1 ]; } vector<vector<int >> preSum (m + 1 , vector<int >(n + 1 , 0 )); for (int i = 1 ; i <= m; ++i) { for (int j = 1 ; j <= n; ++j) { preSum[i][j] = preSum[i - 1 ][j] + preSum[i][j - 1 ] - preSum[i - 1 ][j - 1 ] + nums[i - 1 ][j - 1 ]; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Difference {public : Difference (vector<int >& nums) { diff = vector<int >(nums.size (), 0 ); diff[0 ] = nums[0 ]; for (int i = 1 ; i < nums.size (); ++i) { diff[i] = nums[i] - nums[i - 1 ]; } } void increament (int i, int j, int delta) { diff[i] += delta; if (j + 1 < diff.size ()) { diff[j + 1 ] -= delta; } } vector<int > getArr () { vector<int > ans (diff.size(), 0 ) ; ans[0 ] = diff[0 ]; for (int i = 1 ; i < ans.size (); ++i) { ans[i] = ans[i - 1 ] + diff[i]; } return ans; } private : vector<int > diff; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 vector<int > reservoirSampling (vector<int >& nums, int k) { vector<int > res (k) ; const int n = nums.size (); for (int i = 0 ; i < k; ++i) { res[i] = nums[i]; } for (int i = k; i < n; ++i) { int random = rand () % i; if (random < k) { res[random] = nums[i]; } } return res; }