# 常用內建函式庫
#### Author: PixelCat
----
## 概要
各種常用好用的內建函式庫
---
## 說在前面
----
本篇為參考性質
實際上不需要全記,有印象就好,要用的時候再來查
我信奉的格言是
> 常用的自然會記起來
> 不常用的記了也沒用
----
假如需要某個「疑似內建函數的功能」,直接google有高機率找得到
範例:
> c++ absolute value
就可以找到幫你算絕對值的函數
英文比中文好找
其他技巧請自行在實作中{摸索|~~通靈~~}
----
優質線上文件
1. [cplusplus.com](https://www.cplusplus.com/)
2. [c++ reference](https://en.cppreference.com/w/)
3. [MSDN](https://docs.microsoft.com/zh-tw/cpp/cpp/?view=msvc-160)
google到這幾個的話基本上都可以點進去
---
## 最重要的放前面
關於標頭檔
----
每個函數或STL容器(之後會講到)
都需要include對應的標頭檔
好煩背不完?
----
所有常用函式庫一次滿足
不需要再include其他標頭檔了
```cpp=
#include <bits/stdc++.h>
```
只有在g\++編譯器能用
不過大家都用g++所以沒什麼差
----
以下所有函數
沒特別說的都在命名空間std::裡面
---
## 數學系列
----
```cpp=
#include <cmath>
```
----
### 常用
- `abs(x)` 回傳x的絕對值
- `sqrt(x)` 回傳x的平方根(浮點數)
- `pow(a,x)` 回傳a的x次方
- `ceil(x)` 回傳x向上取整
- `floor(x)` 回傳x向下取整
不建議使用pow計算整數冪次
效率差且有誤差疑慮
請自行實作快速冪
----
### 三角函數系列
三角函數 `cos(x)` `sin(x)` `tan(x)`
反三角函數 `acos(x)` `asin(x)` `atan(x)` `atan2(x)`
1. `atan2` 最常用,細節請查文件
2. 數值單位全部都是弧度(radians)
3. 常用 `pi=acos(-1)`
----
### 對數系列
- `exp(x)` 自然底數e的x次方
- `log(x)` 以e為底的對數
- `log10(x)` 以10為底的對數
- `log2(x)` 以2為底的對數
要用奇怪的底請用換底公式
---
## 實用系列
----
```cpp=
#include <algorithm>
```
----
國小數學比大小
```cpp=
min(a,b)
max(a,b)
```
----
交換兩個東西
```cpp=
swap(a,b)
```
只要兩個型別一樣就可以
----
把 \[l,r) 區間用x填滿
l、r都是一個指標或[迭代器](https://hackmd.io/@PixelCat/rJB-6hVau)
```cpp=
fill(l,r,x)
```
----
把 \[l,r) 區間[排序](https://hackmd.io/@PixelCat/Hk9_m5KH_)
```cpp=
sort(l,r)
stable_sort(l,r)
```
把 \[l,r) 區間隨機打亂
```cpp=
random_shuffle(l,r)
```
把 \[l,r) 區間反轉
```cpp=
reverse(l,r)
```
l、r都是一個指標或[迭代器](https://hackmd.io/@PixelCat/rJB-6hVau)
----
把 \[l,r) 區間的第n小元素放到第n個位置
l、r都是一個指標或[迭代器](https://hackmd.io/@PixelCat/rJB-6hVau)
```cpp=
nth_element(l,r,nth)
```
詳細用法請查文件
----
在 \[l,r) 區間
[二分搜](https://hackmd.io/@PixelCat/S1bNH5YB_)第一個`>=x`的位置
```cpp=
lower_bound(l,r,x)
```
[二分搜](https://hackmd.io/@PixelCat/S1bNH5YB_)第一個`>x`的位置
```cpp=
upper_bound(l,r,x)
```
l、r都是一個指標或[迭代器](https://hackmd.io/@PixelCat/rJB-6hVau)
因為是[二分搜](https://hackmd.io/@PixelCat/S1bNH5YB_)
所以 \[l,r) 區間要是排序過的(由小到大)
----
假如是用自己的結構
此時需要自己提供 `< `運算子
```cpp=
struct Cat{
int age;
int weight;
int color;
};
bool operator<(const Cat &a,const Cat &b){
//肥貓排後面
return a.weight < b.weight;
}
int main(){
Cat cats[50];
//...
sort(cats, cats+50); //OK
}
```
----
假如需要不同的比較方式
例如排序時希望由大到小
也可以自己提供比較函數
```cpp=
bool cmp(int A, int B){
//A應該要排在B前面嗎?
return A > B;
}
int main(){
int a[50];
//...
sort(a, a+50, cmp);
}
```
---
## 記憶體系列
~~系列?~~
----
```cpp=
#include <cstring>
```
多一個c,跟
```cpp=
#include <string>
```
不一樣
----
填滿一塊記憶體
```cpp=
memset(ptr, value, num)
```
參數定義請見文件
例如:把一個陣列全部填成0
```cpp=
int a[500][500];
memset(a, 0, sizeof(a));
```
sizeof是一個關鍵字,找出某個東西占多少記憶體
---
## 時間系列
----
```cpp=
#include <ctime>
```
----
現在時間(以秒為單位)
```cpp=
time(timer)
```
還沒遇過需要給引數的情況,一般計時需求直接
```cpp=
auto t = time(NULL);
```
就可以了
----
精度比較高的版本
```cpp=
clock()
```
請搭配 `CLOCKS_PER_SEC` 服用
----
以上兩個通常用於計時
```cpp=
auto start = clock();
//摸余
//到處摸余
//不斷到處摸余
auto end = clock();
cout << (double)(end - start)/CLOCKS_PER_SEC << "\n";
```
適用於實測程式效率~~壓常、時間剪枝~~
----
這啥?
```cpp=
#include <chrono>
```
我也不知道,多來個時鐘不虧
我自己是沒特別用過(也不會用)
想知道的人左轉文件
---
## 結束系列
名字取好爛
----
```cpp=
assert(exp)
```
假如exp是false
程式直接結束丟RE
適合檢查有沒有漏case ~~二分搜測資~~
----
```cpp=
exit(code)
```
直接以code作為exit code結束程式
不在main裡也有用
---
## 邪門外道系列
----
只在某些環境有辦法用
----
```cpp=
#include <algorithm>
```
回傳兩數的最大公因數
```cpp=
__gcd(a,b)
```
回傳以2為底的對數(比較快)
```cpp=
__lg(x)
```
----
不需include,也不在std::裡面
回傳整數在二進位表示下1的個數
```cpp=
__builtin_popcount(x)
__builtin_popcountll(x)
```
上面的適用32位元無號整數
下面的適用64位元無號整數
----
g++提供的`__builtin_xxx`系列還有很多
可以參考[這篇](http://sunmoon-template.blogspot.com/2017/04/gcc-built-in-functions-for-binary-gcc.html)
---
## 以上
----
只列出我平常比賽、練習有用到的
其他沒在用的就自己去翻文件囉
看過去就可以了,要用再查不然背不完
----
> 常用的自然會記起來
> 不常用的記了也沒用
{"metaMigratedAt":"2023-06-16T04:01:53.072Z","metaMigratedFrom":"YAML","title":"常用函式庫","breaks":true,"slideOptions":"{\"theme\":\"black\",\"transition\":\"slide\"}","contributors":"[{\"id\":\"84d8099a-a721-4db6-8fe4-cfea2a2d82b4\",\"add\":4363,\"del\":291}]"}