1.accumulate
①求和:
第三个参数作为初始值,将区间[first, end)的值相加,返回初始值加上区间总和的值。
需要注意的是,如果总和超出区间中数的类型范围,可以将第三个参数强转成64位的long long类型
#include <iostream> #include <numeric> // std::accumulate #include <vector> int main() { int init = 0; std::vector<int> nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; std::cout << std::accumulate(nums.begin(), nums.end(), init); //output:55 return 0; }
②自定义:
第三个参数传入函数或者对象,自定义函数包含两个参数,第一个参数为初始值,第二个参数将依次传入范围中的值,具体看代码注释;如果是对象,可在在对象中重载operator()实现上述功能
#include <iostream> #include <numeric> // std::accumulate #include <vector> template<class T> class myclass { public: int operator()(T x, T y) { return x + 3 * y; } }; int main() { int init = 0; std::vector<int> nums = { 100, 200, 300}; std::cout << std::accumulate(nums.begin(), nums.end(), init, [&](int x, int y) { return x + 2 * y; }) << std::endl;; //output:55 //output: 0 + 100 * 2 + 200 * 2 + 300 * 2 = 1200 std::cout << std::accumulate(nums.begin(), nums.end(), init, myclass<int>()); //output: 0 + 100 * 3 + 200 * 3 + 300 * 3 = 1800 return 0; }
2.__builtin_ctz / __builtin_ctzll
__builtin系列的函数为GCC编译器的内联函数;
__builtin_ctz:用于计算一个32位数中后导零的数量
cout << __builtin_ctz(16); //16: 10000 ---> output:4
__builtin_ctzll:用于计算一个64位数中后导零的数量
cout << __builtin_ctzll(1LL << 40); //output: 40
3.__builtin_clz / __builtin_clzll
__builtin_clz :用于计算一个32位数的前导零数量
cout << __builtin_clz(8); //(0000 0000 0000 0000 0000 0000 0000 1000) --> output: 28 int LOG = 31 - __builtin_clz(8); //LOG = 3 --> 2^3 = 8
对于一个不是2的幂的数,求它以2为底的对数,用上述第二段代码求得的是向下取整之后的值
int LOG = 31 - __builtin_clz(15); //(0000 0000 0000 0000 0000 0000 0000 1111) LOG = 3
__builtin_clzll:用于计算一个64位数的前导零数量
3.__builtin_popcount
用于计算一个数的二进制中1的个数
cout << __builtin_popcount(15); //output: 4
4.bitset
bitset类模拟了存放bool类型的array ,但是对其做了空间优化,每个元素0或1都只占用了一个位,并且可以用 [ ] 访问每一位的值
4.1 参数
4.2 构造函数
#include <iostream> #include <bitset> #include <string> int main() { std::bitset<16> foo; std::bitset<16> bar(0xfa2); std::bitset<16> baz("0101111001"); std::cout << foo; //output:0000000000000000 std::cout << bar; //output:0000111110100010 std::cout << baz; //output:0000000101111001 return 0; }
4.3 成员函数
①operator[]
int main() { std::bitset<8> bs; for (int i = 0; i < bs.size(); i++) { bs[i] = 1; } std::cout << bs; //output: 11111111 }
②count 返回1的个数
int main() { std::bitset<8> bs(15); std::cout << bs.count(); //output: 4; }
③to_string 转为string类型
④to_ullong 转为 unsigned long long类型
其他:bitset - C++ Reference (cplusplus.com)
5.lower_bound / upper_bound
C++标准库自带的二分查找算法,对于lower_bound(val),函数返回 [first, last) 范围内val下限(第一个大于等于val)位置的迭代器,而upper_bound则是返回 [first, last) 范围内val上限(第一个大于val)位置的迭代器
#include <iostream> // std::cout #include <algorithm> // std::lower_bound, std::upper_bound, std::sort #include <vector> // std::vector int main() { int myints[] = { 10,20,30,30,20,10,10,20 }; std::vector<int> v(myints, myints + 8); // 10 20 30 30 20 10 10 20 std::sort(v.begin(), v.end()); // 10 10 10 20 20 20 30 30 std::vector<int>::iterator low, up; low = std::lower_bound(v.begin(), v.end(), 20); up = std::upper_bound(v.begin(), v.end(), 20); std::cout << "lower_bound at position " << (low - v.begin()) << '\n'; //output: 3 std::cout << "upper_bound at position " << (up - v.begin()) << '\n'; //output: 6 return 0; }
需要注意的是,对于如vector这类支持随机迭代器的容器使用lower_bound/upper_bound函数的时间复杂度为logN, 而对于set/multiset这类不支持随机迭代器的容器,使用库函数的lower_bound/upper_bound函数的时间复杂度为N* logN,
而set/multiset中也有实现二分查找的同名成员函数,时间复杂度为logN
算法运用:有序集合 + 滑动窗口
2817. 限制条件下元素之间的最小绝对差220. 存在重复元素 III
6.min_element / max_element
返回区间 [first, last) 中最小值的迭代器
// min_element/max_element example #include <iostream> // std::cout #include <algorithm> // std::min_element, std::max_element #include <vector> int main() { std::vector<int> arr = { 3,7,2,5,6,4,9 }; // using default comparison: std::cout << "The smallest element is " << *std::min_element(arr.begin(), arr.end()); std::cout << "The largest element is " << *std::max_element(arr.begin(), arr.end()); return 0; }
7.iota
见文章【C++】iota函数 + sort函数实现基于一个数组的多数组对应下标绑定排序_Dusong_的博客-CSDN博客