算法竞赛常用函数整理(C++)

算法竞赛常用函数整理(C++)

这篇文章整理了算法竞赛中经常用到的 C++ 函数,适合刷题或考前复习,会持续更新...

memset

作用:将指定内存块的前num个字节设置为指定值

头文件

#include <cstring>

使用

void* memset(void* ptr, int value, size_t num);
// ptr:目标内存块的起始地址
// value:要设置的值(以字节为单位)
// num:要设置的字节数

例子

// 将数组全部初始化为0
int arr[100];
memset(arr, 0, sizeof(arr)); 

// 将字符数组初始化为'*'
char str[50];
memset(str, '*', 10); // 前10个字节设为'*'

注意事项

  • 按字节设置,不适合初始化非字符类型的复杂值(如-1int有效,因补码一致)

  • 不能直接用于vector(需用vector.assignfill

  • C++ 版本:C++98+

to_string

作用:将数字常量转换为字符串

头文件

#include <string>

使用

string to_string(int val);
string to_string(long val);
string to_string(long long val);
string to_string(float val);
string to_string(double val);
// 支持多种数值类型转换

例子

string s1 = to_string(123); // s1 = "123"
string s2 = to_string(3.14); // s2 = "3.140000"
string s3 = to_string(-456LL); // s3 = "-456"

注意事项

  • 浮点数转换会包含默认精度(如double保留 6 位小数)

  • C++ 版本:C++11+

isdigit

作用:判断字符是否为数字(0-9)

头文件

#include <cctype>

使用

int isdigit(int c); // c为字符的ASCII值,返回非0表示是数字,0表示不是

例子

string s = "abc123def45";
int cnt = 0;
for (char c : s) {
    if (isdigit(c)) cnt++; // 统计数字个数,结果为5
}

注意事项

  • 需传入char的 ASCII 值(直接传字符变量即可)

  • 对负数或非字符值行为未定义

  • C++ 版本:C++98+

sqrt

作用:计算平方根

头文件

#include <cmath>

使用

double sqrt(double x);
float sqrt(float x);
long double sqrt(long double x);

例子

double res1 = sqrt(25.0); // res1 = 5.0
float res2 = sqrt(10.0f); // res2 ≈ 3.16228f

注意事项

  • 输入x需非负,否则返回 NaN(浮点数)

  • C++ 版本:C++98+

exp

作用:计算自然常数ex次方(e^x)

头文件

#include <cmath>

使用

double exp(double x);
float exp(float x);
long double exp(long double x);

例子

double res = exp(1.0); // res ≈ 2.71828(e^1)

C++ 版本:C++98+

pow

作用:计算xy次方(x^y)

头文件

#include <cmath>

使用

double pow(double x, double y);
float pow(float x, float y);
long double pow(long double x, long double y);

例子

double res1 = pow(2.0, 3.0); // res1 = 8.0(2^3)
double res2 = pow(10.0, 2.5); // res2 ≈ 316.227766(10^2.5)

注意事项

  • x为负数且y非整数,结果为 NaN

  • C++ 版本:C++98+

log、log10

作用log计算自然对数(ln x),log10计算以 10 为底的对数(lg x)

头文件

#include <cmath>

使用

double log(double x); // ln x
double log10(double x); // lg x

例子

double res1 = log(exp(1.0)); // res1 = 1.0(ln e = 1)
double res2 = log10(1000.0); // res2 = 3.0(lg 1000 = 3)

注意事项:输入x必须为正数,否则返回 NaN

C++ 版本:C++98+

abs、fabs

作用abs计算整数绝对值,fabs计算浮点数绝对值

头文件

#include <cmath> // fabs
#include <cstdlib> // abs(整数)或直接用std::abs(C++11+)

使用

// 整数绝对值
int abs(int x);
long abs(long x);
long long abs(long long x);

// 浮点数绝对值
double fabs(double x);
float fabs(float x);

例子

int a = abs(-5); // a = 5
double b = fabs(-3.14); // b = 3.14

C++ 版本:C++98+

ceil、floor、round

作用

  • ceil(x):向上取整(返回大于等于x的最小整数)

  • floor(x):向下取整(返回小于等于x的最大整数)

  • round(x):四舍五入到最近整数

    头文件

#include <cmath>

使用

double ceil(double x);
double floor(double x);
double round(double x);

例子

double c = ceil(2.3); // c = 3.0
double f = floor(2.7); // f = 2.0
double r = round(2.5); // r = 3.0

C++ 版本:C++98+

modf、fmod

作用

  • modf(x, &iptr):拆分x为整数部分(通过iptr返回)和小数部分(返回值)

  • fmod(x, y):计算x除以y的余数(x = k*y + 余数,余数与x同号)

    头文件

#include <cmath>

使用

double modf(double x, double* iptr);
double fmod(double x, double y);

例子

// modf示例
double x = 3.14, int_part;
double frac_part = modf(x, &int_part); // int_part = 3.0,frac_part = 0.14

// fmod示例
double rem = fmod(7.5, 2.0); // rem = 1.5(7.5 = 3*2.0 + 1.5)

C++ 版本:C++98+

rand

作用:生成伪随机整数(范围 0~RAND_MAX,通常为 32767)

头文件

#include <cstdlib>

使用

int rand(void);

例子

// 生成1~100的随机数
srand(time(0)); // 用当前时间初始化随机数种子
int num = rand() % 100 + 1; // 范围[1, 100]

注意事项

  • 需用srand初始化种子(通常结合time(0)),否则每次运行结果相同

  • 随机性较差,竞赛中建议用mt19937(见下文)

  • C++ 版本:C++98+

sort

作用:对区间内元素进行排序(默认升序,可自定义排序规则)

头文件

#include <algorithm>

使用

// 对数组排序
void sort(RandomAccessIterator first, RandomAccessIterator last);
// 自定义排序规则
void sort(RandomAccessIterator first, RandomAccessIterator last, Compare cmp);

例子

// 数组排序
int arr[] = {3, 1, 4, 1, 5};
sort(arr, arr + 5); // 升序:[1,1,3,4,5]

// vector排序
vector<int> v = {5, 2, 7};
sort(v.begin(), v.end(), greater<int>()); // 降序:[7,5,2]

// 自定义结构体排序(Lambda表达式)
struct Point { int x, y; };
vector<Point> pts = {{2,3}, {1,4}, {3,1}};
sort(pts.begin(), pts.end(), [](const Point& a, const Point& b) {
    return a.x < b.x; // 按x升序
});

注意事项

  • 自定义比较函数cmp作为类成员时需加static修饰

  • Lambda 表达式比普通函数效率更高

  • C++ 版本:C++98+

lower_bound、upper_bound

作用:在有序区间内进行二分查找

  • lower_bound:返回第一个大于等于目标值的元素位置

  • upper_bound:返回第一个大于目标值的元素位置

    头文件

#include <algorithm>

使用

// 查找[first, last)中首个>=val的位置
ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& val);

// 查找[first, last)中首个>val的位置
ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, const T& val);

例子

vector<int> v = {1, 3, 5, 5, 7};
// 查找>=5的第一个位置
auto it1 = lower_bound(v.begin(), v.end(), 5); // 指向索引2(值5)
// 查找>5的第一个位置
auto it2 = upper_bound(v.begin(), v.end(), 5); // 指向索引4(值7)

int pos1 = it1 - v.begin(); // pos1 = 2
int pos2 = it2 - v.begin(); // pos2 = 4

注意事项:需确保区间已排序(升序),否则结果未定义

C++ 版本:C++98+

reverse

作用:反转区间内元素的顺序

头文件

#include <algorithm>

使用

void reverse(BidirectionalIterator first, BidirectionalIterator last);

例子

// 反转数组
int arr[] = {1,2,3,4};
reverse(arr, arr + 4); // 结果:[4,3,2,1]

// 反转字符串
string s = "hello";
reverse(s.begin(), s.end()); // 结果:"olleh"

C++ 版本:C++98+

max_element、min_element

作用

  • max_element:返回区间内最大值的迭代器

  • min_element:返回区间内最小值的迭代器

    头文件

#include <algorithm>

使用

ForwardIterator max_element(ForwardIterator first, ForwardIterator last);
ForwardIterator min_element(ForwardIterator first, ForwardIterator last);

例子

vector<int> v = {3, 1, 4, 2};
// 找最大值
auto max_it = max_element(v.begin(), v.end());
int max_val = *max_it; // 4
int max_pos = max_it - v.begin(); // 2(索引)

// 找最小值
auto min_it = min_element(v.begin(), v.end());
int min_val = *min_it; // 1
int min_pos = min_it - v.begin(); // 1(索引)

注意事项:若有多个相同最值,返回第一个出现的位置

C++ 版本:C++98+

__builtin_popcount、__builtin_popcountll(GCC 扩展)

作用:计算整数二进制表示中 1 的个数(内置位运算函数)

头文件:无(GCC 编译器内置)

使用

int __builtin_popcount(unsigned int x); // 32位无符号整数
int __builtin_popcountll(unsigned long long x); // 64位无符号整数

例子

int cnt1 = __builtin_popcount(0b1010); // 2(二进制1010有2个1)
int cnt2 = __builtin_popcountll(0b111000ULL); // 3(64位下111000有3个1)

注意事项:仅 GCC 编译器支持,输入需为无符号整数

C++ 版本:GCC 扩展(兼容 C++98+)

stoi、stoll、stof

作用:将字符串转换为整数 / 长整数 / 浮点数

头文件

#include <string>

使用

int stoi(const string& str, size_t* pos = 0, int base = 10); // 转int
long long stoll(const string& str, size_t* pos = 0, int base = 10); // 转long long
float stof(const string& str, size_t* pos = 0); // 转float

例子

int a = stoi("123"); // 123
long long b = stoll("123456789012"); // 123456789012
float c = stof("3.14"); // 3.14f

// 指定进制(如二进制"1010"转十进制)
int d = stoi("1010", nullptr, 2); // 10

注意事项:字符串格式错误或超出范围会抛异常

C++ 版本:C++11+

mt19937(随机数生成器)

作用:高性能伪随机数生成器(梅森旋转算法)

头文件

#include <random>

使用

std::mt19937 rng(seed); // seed为种子(通常用std::random_device{}())

例子

// 初始化随机数生成器
std::random_device rd;
std::mt19937 rng(rd()); // 用硬件随机种子初始化

// 生成[1, 100]的随机整数
std::uniform_int_distribution<int> dist(1, 100);
int num = dist(rng); // 每次调用生成不同随机数

注意事项:随机性远优于rand(),竞赛中优先使用

C++ 版本:C++11+

gcd、lcm

作用gcd(a,b)计算最大公约数,lcm(a,b)计算最小公倍数

头文件

#include <numeric>

使用

template<class T> T gcd(T a, T b); // C++17+
template<class T> T lcm(T a, T b); // C++17+

例子

int g = gcd(12, 18); // 6
int l = lcm(12, 18); // 36

注意事项:输入需为非负整数,lcm计算为(a/gcd(a,b))*b(避免溢出)

C++ 版本:C++17+

next_permutation、prev_permutation

作用:生成区间的下一个 / 上一个字典序排列(需已排序)

头文件

#include <algorithm>

使用

bool next_permutation(BidirectionalIterator first, BidirectionalIterator last);
bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last);

例子

string s = "123";
next_permutation(s.begin(), s.end()); // s = "132"(下一个排列)
prev_permutation(s.begin(), s.end()); // s = "123"(上一个排列)

注意事项:若已为最后 / 最前排列,返回false,否则返回true并修改区间

C++ 版本:C++98+

string 成员函数(substr、find、c_str)

作用

  • substr:截取子字符串

  • find:查找子串位置

  • c_str:转换为 C 风格字符串(const char*

    头文件

#include <string>

使用

// 截取子串:从pos开始,长度为len(默认到结尾)
string substr(size_t pos = 0, size_t len = npos) const;

// 查找子串:从pos开始找str,返回位置(未找到返回string::npos)
size_t find(const string& str, size_t pos = 0) const;

// 转换为C风格字符串
const char* c_str() const;

例子

string s = "abcdef";
string sub = s.substr(1, 3); // "bcd"(从索引1开始,取3个字符)

size_t pos = s.find("cd"); // 2("cd"在索引2开始)

const char* cstr = s.c_str(); // 转换为const char*(用于printf等)

C++ 版本:C++98+

unordered_map(哈希映射)

作用:存储键值对,支持 O (1) 平均复杂度的插入、查找、删除

头文件

#include <unordered_map>

常用操作

// 插入键值对
void insert(const pair<Key, Value>& p);
// 访问/插入值(若键不存在则默认构造)
Value& operator[](const Key& key);
// 查找键(返回迭代器)
iterator find(const Key& key);
// 删除键
size_t erase(const Key& key);

例子

unordered_map<string, int> mp;
mp["apple"] = 5; // 插入键值对("apple",5)
mp.insert({"banana", 3});

if (mp.find("apple") != mp.end()) {
    cout << mp["apple"]; // 输出5
}

mp.erase("banana"); // 删除键"banana"

注意事项:无序存储,键需支持哈希(自定义类型需提供哈希函数)

C++ 版本:C++11

posted @ 2025-07-29 22:16  Zyihan_Crz  阅读(287)  评论(0)    收藏  举报