首页 > 其他分享 >比较实用的语法糖

比较实用的语法糖

时间:2023-07-01 11:33:45浏览次数:43  
标签:返回 实用 bg val ed 复杂度 语法 比较 sim

《从 C++98 到 C++20,寻觅甜甜的语法糖们》

这篇文章对《从 C++98 到 C++20,寻觅甜甜的语法糖们》稍有改动

  • find(bg,ed,val)

    • 返回指向第一个等于 \(val\) 的元素的指针。

    • 时间复杂度 \(O(n)\)。

    • 后文所有序列操作的函数,都以 \(n\) 代指 \(ed−bg\)。

  • fill(bg,ed,val)

    • 将 \(bg \sim ed\) 之间的所有元素赋值为 \(val\)。

    • 复杂度为 \(O(n)\),常数略大于 memset

    • val = 0x3f 时常数与 memset 相同。(存疑)

    • 常用于弥补 memset 无法赋值的问题,如赋值一个数组为 \(1\)。

  • max_element/min_element(bg,ed)

    • 返回指向 \(bg \sim ed\) 中最大/最小的元素的指针。

    • 时间复杂度 \(O(n)\)。

    • 第三个参数可传入比较函数。

    • 求数组最大值就可以直接写:*max_element(a+1,a+n+1)

  • nth_element(bg,md,ed):

    • 将 \(bg \sim ed\) 中的内容重新分配顺序,\(\le\) md 的元素在 \(bg \sim md\),\(\ge\) md 的元素都在 \(md \sim ed\)。

    • 时间复杂度 \(O(n)\),需要 \(O(n)\) 的额外空间。

    • 第四个参数为比较函数,若不传则默认 less<>()

    • 常用于线性求序列中的第 \(k\) 大,常用于实现替罪羊树。

  • stable_sort(bg,ed)

    • 对 \(bg \sim ed\) 进行 稳定 排序。

    • 时间复杂度 \(O(n log ⁡n)\),要 \(O(n)\) 的额外空间。

    • 当空间不足时使用 \(O(n log⁡_2 n)\) 的双调排序。

  • next_permutation(bg,ed)

    • 将 \(bg \sim ed\) 更改为下一个排列,并返回 \(1\)。

    • 若 \(bg \sim ed\) 已经是最后一个排列,那么返回 \(0\)。

    • 下一个排列的定义为字典序严格大于当前排列的下一个排列。

    • 时间复杂度 \(O(n)\)。

    • 事实上 \(bg \sim ed\) 不一定要是排列,可以存在相同元素。

    • 常用于枚举全排列:

    do{
    	// ...
    }while(next_permutation(p,p+n));
    
    • prev_permutation(bg,ed) 可以求出上一个排列。
  • merge(bg1,ed1,bg2,ed2,bg3)

    • \(bg1 \sim ed1\) 和 \(bg2 \sim ed2\) 是两个有序序列,对其进行归并并存入 bg3

    • 不能够原地归并,若要原地归并请使用 inplace_merge

    • 时间复杂度 \(O(ed1−bg1+ed2−bg2)\)。

    • 可以传入第六参数作为比较函数。

  • inplace_merge(bg,md,ed)

    • 将 \(bg \sim md\) 和 \(md \sim ed\) 归并排序,并存入 bg

    • 时间复杂度 \(O(n)\),需要 \(O(n)\) 的额外空间。

    • 当空间不足时使用 \(O(n log⁡ n)\) 的原地排序。

    • 常数较小,可能比手写的还快。

    • 可以传入第四个参数作为比较函数。

    • 常用于 CDQ 分治等分治算法,非常好用。

  • count(bg,ed,val)

    • 返回 \(bg \sim ed\) 中等于 \(val\) 的元素的个数。

    时间复杂度 \(O(n)\)。

  • count_if(bg,ed,func)

    • 返回 \(bg \sim ed\) 中使得函数 func 返回值为 \(\true\) 的元素的个数。

    • 时间复杂度 \(O(n \times f)\),\(f\) 为 func 的复杂度。

    • 常用的 func 有:islower/isupper/isdigit 等。

  • replace(bg,ed,val1,val2)

    • 将 \(bg \sim ed\) 中所有等于 \(val1\) 的元素替换为 \(val2\)。

    • 时间复杂度 \(O(n)\)。

  • for_each(bg,ed,func)

    • 对 \(bg \sim ed\) 中所有元素执行函数 func

    • 时间复杂度 \(O(n \times f)\)。

    • 其实没啥用,就是能压行。

  • accumulate(bg,ed,val)

    • 将 \(bg \sim ed\) 中的所有所有元素与初始值 \(val\) 相加,返回这个和。

    • 时间复杂度 \(O(n)\)。

    • 可以传入第四个参数作为加法。

    • 可以用于求序列和,但注意,该函数返回值与 \(val\) 类型一致,意味着你要注意 long long 的问题:

    accumulate(bg,ed,0);//返回值是 int,可能溢出
    accumulate(bg,ed,0ll);//返回值是 long long
    
  • fabs(x)

    • 返回 \(∣x∣\)。

    • 注意,对浮点运算请都使用 fabs 而不是 abs,因为有可能你调用的是 abs(int)

  • ceil(x)

    • 返回 \(⌈x⌉\)

    • 其返回值依旧是浮点类型,输出时注意格式。

  • floor(x)

    • 返回 \(⌊x⌋\)

    • 其返回值依旧是浮点类型,输出时注意格式。

  • shuffle(bg,ed,gen)

    • 打乱 \(bg \sim ed\) 的顺序,gen 是一个随机数生成器(mt19937)。

    • 时间复杂度 \(O(n)\)。

    • C++11 之后请尽量使用 shuffle 而不是 random_shuffle

  • is_sorted(bg,ed)

    • 判断 \(bg \sim ed\) 是否升序排序。

    • 时间复杂度 \(O(n)\)。

  • minmax(a,b)

    • 返回一个 pair<>,其 first 为 \(\min⁡(a,b)\),second 为 \(\max⁡(a,b)\)。

    • 时间复杂度 \(O(1)\)。

    • 常用于无向图存边的去重问题。

  • exp2(x)

    • 返回 \(2^x\)。
  • log2(x)

    • 返回 \(log_2(x)\)
  • hypot(x,y)

    • 返回 \(\sqrt {x^2 + y^2}\)

    • 常用于求两点之间的距离,非常方便。

  • hypot(x,y,z)

    • 返回 \(\sqrt {x^2 + y^2 + z^2}\)

    • 复杂度 O(1)。

    • 常用来求三维中两点距离。

  • mt19937

    • 一个类型,作为随机数生成器。

    • 其构造函数应传入一个数字作为随机种子,使用时用法和 \(rand\) 相同。

    • 生成 unsigned int 范围内的随机数。

    mt19937 gen(123456); //123456 为随机种子
    int x = gen()%10000; //x will in [0,10000]
    uint32_t y = gen(); //normally y will in [0,2^32]
    
    • 随机种子通常为时间相关,下面的非常常用,建议背过
    mt19937 gen(chrono::system_clock::now().time_since_epoch().count());//chrono 在头文件 <chrono> 中
    
  • uniform_int_distribution(L,R)

    • 随机数发生器,每次调用时传入一个 mt19937,返回一个 \(L \sim R\) 之间的整数,类型为 \(T\),若 \(T\) 为空则默认为 int
  • uniform_real_distribution(L,R)

    • 随机数发生器,每次调用时传入一个 mt19937,返回一个 \(L \sim R\) 之间的实数,类型为 \(T\),若 \(T\) 为空则默认为 double
  • gcd(x,y) 或 lcm(x,y)

    • 返回 \(\gcd(|x|,|y|)\) 或 \(\operatorname {lcm}(|x|,|y|)\) 的值。

    • 复杂度对数级别的。

    • 保证了返回值的符号是正。

    • \(\operatorname {lcm}\) 的实现是先除后乘。

  • popcount(x)

    • 返回无符号整形 \(x\) 在二进制下 \(1\) 的个数。

    • 时间复杂度有说 \(O( \log⁡⁡ \log x)\) 的,也有说 \(O(1)\) 的,一定比手写的快。

    • 使用 __builtin_popcount 实现,但会检查传入的参数是否为无符号整形。

countl_zero(x);//从最高位起连续的 0 的数量
countr_zero(x);//从最低位起连续的 0 的数量
countl_one(x);//从最高位起连续的 1 的数量
countr_one(x);//从最低位起连续的 1 的数量
  • bit_width(x)

    • 当 \(x = 0\) 时返回 \(0\),否则返回 \(1+⌊log⁡2(x)⌋\)。

    • 即二进制下 \(x\) 的位数。

    • 复杂度 \(O(1)\)。

  • bit_floor(x)/bit_ceil(x)

    • 返回不超过 \(x\) 的最大的 \(2\) 的整次幂 / 不小于 \(x\) 的最小的 \(2\) 的整次幂。

    • 复杂度 \(O(1)\)。

  • has_single_bit(x)

    • 返回 \(x\) 是否为 \(2\) 的整次幂,相当于 popcount(x)==1

    • 复杂度 \(O(1)\)。

  • numbers 库

头文件 <numbers>,命名空间 std::numbers 中提供了大量的数学常数:

代码表示 数学表示
e_v \(e\)
log2e_v \(log_{2}e\)
pi_v \(\pi\)
log10e_v \(log_{10}e\)
inv_pi_v \(\frac{1}{\pi}\)
inv_sqrtpi_v \(\frac{1}{\sqrt{\pi}}\)
ln2_v \(\operatorname{ln}2\)
ln10_v \(\operatorname{ln}10\)
sqrt2_v \(\sqrt{2}\)
sqrt3_v \(\sqrt{3}\)
inv_sqrt3_v \(\frac{1}{\sqrt{3}}\)
egamma_v 欧拉-马斯克若尼常数 \(γ\)
phi_v 黄金比 \(ϕ= \frac{\sqrt5+1}{2}\)(注意这里是加号!!!)
  • 这些都是类模板,调用时请填入类型:
int main(){
  std::cout<<std::fixed<<std::setprecision(9)<<std::numbers::pi_v<double><<'\n';
}

去掉末尾的 _v 后直接就是一个常量:

cout<<numbers::e<<'\n';

标签:返回,实用,bg,val,ed,复杂度,语法,比较,sim
From: https://www.cnblogs.com/LKJZYD20/p/17519050.html

相关文章

  • Java基础语法
    Java语法快速入门1.1程序的入口#java程序入口为类中的static的viod的main函数,参数固定为字符串数组publicstaticvoidmain(String[]args){System.out.println("helloworld");}1.2文件名#一个文件中最多只能有一个public类且【文件名】必须和【public类名......
  • Typora语法
    MarkDown基本语法正式开始语法部分~标题 #标题名字(井号的个数代表标题的级数) #一级标题 ##二级标题 ###三级标题 ####四级标题 #####五级标题 ######六级标题 #######最多支持六级标题段落段落没有特殊的格式,直接用一个空行来表示重新开始一个段落。文字斜......
  • 光脚丫学LINQ(013):LINQ查询语法与方法语法
    视频演示:http://u.115.com/file/f2f1e1a2f4 通过使用C#3.0中引入的声明性查询语法,介绍性LINQ文档中的多数查询都被编写为查询表达式。但是,.NET公共语言运行时(CLR)本身并不具有查询语法的概念。因此,在编译时,查询表达式会转换为CLR确实了解的内容:方法调用。这些方法称为......
  • Java-语法基础
    JDK8复习用Java前置知识JavaSEJavaStandardEdition标准版支持面向桌面级应用(如Windows下的应用程序)的Java平台,提供了完整的Java核心API此版本以前称为J2SEJavaEEJavaEnterpriseEdition企业版一套用于企业环境下的应用程序的应用方案(包含:Servlet、Jsp),主要针......
  • Java基础语法
    1、Java的八种基本数据类型1、byte1字节取值范围:-128~1272、short2字节取值范围:-32768~327673、int4字节取值范围:-231~231-1#int是开发中最常用的,也是Java中默认的数据类型4、long8字节取值范围:-263~263-1#声明超过int取值范围的lon......
  • 展开语法和剩余语法(剩余参数)都是三个点...
    展开语法(Spreadsyntax),可以在函数调用/数组构造时,将数组表达式或者string在语法层面展开;还可以在构造字面量对象时,将对象表达式按key-value的方式展开;剩余参数语法允许我们将一个不定数量的参数表示为一个数组。区别是展开语法是把一个变量展开,剩余参数是一个参数用来代......
  • Python学习入门,从19个语法开始!
    Python简单易学,但又博大精深。许多人号称精通Python,却不会写Pythonic的代码,对很多常用包的使用也并不熟悉。学海无涯,我们先来了解一些Python中最基本的内容。Python的特点解释型语言,无需编译即可运行提供了交互式命令行基于对象的编程思想跨平台和良好的兼容性,在Windows、Mac、Linu......
  • vue3+tsx开发语法详解
    参考链接vue3+tsx开发语法详解vue3官方文档和jsx的使用......
  • 正则的定义及语法
    正则的定义正则就是规则,用来操作字符串的,判断字符串格式是否正确。正则就是用来验证字符串的。正则写法语法:正则字面量(字符串)varreg=//reg就可以验证字符串。正则对象语法:创建正则对象对象:newRegExp(模式,修饰符);正则对象和正则字符串的区别(1)正则对象......
  • Three.js教程:threejs语法总结
    推荐:将NSDT场景编辑器加入你的3D工具链其他系列工具:NSDT简石数字孪生threejs语法总结本节课从JavaScript面向对象语法的角度,给大家总结下threejsAPI的使用习惯,这样方便大家更好的使用threejsAPI。Three.js语法总结:类(构造函数)Three.js提供了各种各样的类(构造函数),通过ne......