auto、lambda、pbds

1. auto

1.1 auto是干什么的

auto是一个很抽象的玩意,例如你需要一个类型存储这个玩意:

??? x=1;

然后你忘了...(反正我不知道是 int

这个时候你就可以掏出 auto,即

auto x=1;

1.2 auto做 A+B Problem

代码如下:

#include<bits/stdc++.h>
using namespace std;
auto read()
{
	auto x=0,f=1;auto ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
main()
{
    auto a=read(),b=read();
    cout<<a+b;
    return 0;
}

我们可以发现,这里没有用到 int

下次不记得该用什么变量,就可以用auto。

1.3 auto代替迭代器

xxx:我蚌埠(崩不)住了,说的我们不会 intchar 似的。

好像很有道理,那么看下面这个东西:

vector<int> vt;
for(vector<int>::iterator it=vt.begin();it!=vt.end();it++)
	cout<<"#"<<i<<" is "<<vt[it]<<endl;

古语有云:

你说的对,但是 auto 是什么?是能代替一切(除signed main()处)类型的大佬!——《你说得对·auto》

所以我们可以改成:

vector<int> vt;
for(auto it=vt.begin();it!=vt.end();it++)
	cout<<"#"<<i<<" is "<<vt[it]<<endl;

xxx:auto 就这?int 也能做到!

古语有云:

你说的对,但是 auto 是什么?是能代替一切(除signed main()处)类型的大佬!——《你说得对·auto》

所以我们可以改成:

vector<int> vt;
for(auto it:vt)
	cout<<"#"<<i<<" is "<<it<<endl;

这样写的 auto 是可以代替整个 vt[it] 的。

1.4 auto的注意事项

你说得对,但是 auto 是由c++自主研发的一款需要定义即赋值的数据类型……——《你说的对·auto》

如果定义:

auto YR;

c++是会报错的,因为 auto 无法判断 YR 的数据类型,然后就***了。

所以 auto 定义就需要赋值。

2. lambda表达式

2.1 百度的lambda

[capture list] (parameter list) -> return type { function body }

什么鬼?看不懂一点。

好吧,还是看不懂...

2.2 lambda

我们先不管捕获列表,先看后面的。

lambda 类似于一个临时函数,函数是这样的:

type (parameter)
{
	function bofy;
}

或者说,是这样的:

函数类型 (参数)
{
	函数体;
}

lambda也是一样的。例如临时比较 x,yx,y 的大小,可以写作:

[](int x, int y){return x > y;}

如果要比较任意两个元素呢?这又要说到古语了:

你说的对,但是 auto 是什么?是能代替一切(除signed main()处)类型的大佬!——《你说得对·auto》

[](auto x, auto y){return x > y;}

那么在以前排序:

auto cmp(auto A, auto B)
{
	return A > B;
}
int main()
{
	...
	sort(a + 1, a + n + 1, cmp);
	...
}

现在:

sort(a + 1, a + n + 1, [](auto x, auto y){return x > y;});

2.3 不知道返回类型?

如果你不知道返回类型是什么,请尝试 auto

2.4 捕获列表怎么用?

捕获列表是用来传参的。

例如比较 a,xa,x 的大小(xx 为定值),我们可以这么写:

[x](int a){return a > x}

他也可以引用后修改,例如:

[&](int a){return ++ a;}

2.5 lambda的一些闲话

  • λ\lambda$\lambda$
  • lambda 可嵌套使用

3. pbds

3.1 引入

xxx:平衡树多可爱,我太tm的爱打了!

爱打就打,pbds=yyds

3.2 pbds能干嘛?

pbds是一个非常棒的STL(尽管他不是),里面支持 hash(哈希,map)、tree(平衡树)、trie(字典树)、priority_queue(优先队列,堆)。

3.3 pbds的头文件

不长,就这样:

#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>//哈希
#include<ext/pb_ds/tree_policy.hpp>//平衡树
#include<ext/pb_ds/trie_policy.hpp>//字典树
#include<ext/pb_ds/priority_queue.hpp>//优先队列
using namespace __gnu__pbds;

再短一点就是这样:

#include<bits/extc++.h>
using namespace __gnu__pbds;

推荐用上面的,用下面的会出现一些莫名其妙的错误

3.4 pbds之hash篇

是这么定义的:

cc_table_hash<int, int> h;
gp_table_hash<int, int> h;

你就当它们没什么区别好了(gp快一点)

pbds_hashmap 差不太多,都能用 []find(x)

举个例子:

cc_table_hash<int, int> h;
for(int i = 1; i <= n; i++)
	cin >> a[i], h[a[i]]=i;
int n;
cin >> n ;
auto x = h[n];
cout << x;

map时间复杂度 O(nlogn)O(n\log n),但是hash的复杂度只有 O(n)O(n)

3.5 pbds之trie

  • insert 插入一个字符串,返回一个 pair<it,bool> 表示迭代器和是否插入成功。
  • erase 删除一个字符串,返回 bool 表示是否删除成功。
  • join(b)bb 树加入并清空 bb 树。
  • find 寻找一个字符串,返回迭代器,找不到返回 end。
  • begin 返回第一个迭代器。
  • end 返回最后一个的下一个的迭代器。
  • --/++ 下一个或上一个迭代器。
  • prefix_range(x) 返回一个 pair 表示前缀为 xx 的迭代器范围,使用时类似:
auto range=tr.prefix_range(x);
for(auto it=range.first;it!=range.second;it++);

来遍历前缀为 xx 的所有字符串。

4. 最后的最后

auto好闪!拜谢auto!

posted @ 2024-07-10 10:57  sLMxf  阅读(32)  评论(0)    收藏  举报  来源