【C++入门精讲19】bitset位图 | 仿函数 | Lambda表达式 | bind绑定器 | STL算法全套实战
前言
本篇为本人手写全套实战笔记,包含 bitset位图操作、自定义仿函数、STL内置仿函数、Lambda表达式、bind参数绑定器、STL常用算法。
一、bitset 位图容器(位运算神器)
1.1 核心概念
bitset<N>:固定N位二进制位图容器,默认全部置0,专门用于位运算、权限判断、状态标记、进制转换。
优势:极度省内存、位运算效率极高。
1.2 常用API
-
set():所有位置1 -
set(pos,val):指定位置置0/1 -
reset():所有位置0 -
flip():所有位按位取反 -
to_ulong():二进制转十进制 -
支持位运算:
& | ^ ~ -
支持位图之间判等
==
1.3 完整实战代码
#include<iostream>
#include<bitset>
using namespace std;
int main() {
// 固定2位二进制,默认全0
bitset<2> pb;
cout << pb << endl;
pb.set(); // 全部置1
cout << pb << endl;
pb.reset(); // 全部重置为0
pb.set(0, 1); // 第0位置1
cout << pb << endl;
// 字符串转二进制位图
bitset<8> pbs("10101010");
// 十进制数值转二进制位图
bitset<3> fb(6);
cout << fb << endl;
fb.flip(); // 所有位取反
cout << fb << endl;
// 位图比较
bitset<3> fb2(5);
cout << (fb2 == fb) << endl;
// 权限位运算模拟
bitset<3> r(4), w(2), x(1);
// 判断是否拥有x权限
if ((fb2 & x) == x) {
cout<<"具有可执行权限"<<endl;
}
// 增加w权限
fb2 |= w;
cout << fb2 << endl;
// 移除w权限(异或翻转)
fb2 ^= w;
cout << fb2 << endl;
// 二进制字符串转十进制
bitset<8> data("1001001");
cout << data.to_ulong() << endl;
// 字符转二进制(a=97)
bitset<8> data2('a');
cout << data2 << endl;
return 0;
}
1.4 课后练习代码
#include<iostream>
#include<string>
using namespace std;
// 自定义仿函数类
class F {
public:
void operator() (const string &info) const{
cout << "info:"<<info << endl;
}
};
int main() {
F f;
f("hello world"); // 像函数一样调用
return 0;
}
二、仿函数(函数对象)
2.1 核心概念
仿函数:重载了 operator() 的类对象,可以像函数一样调用。
特点:可以保存成员变量状态、支持一元/二元运算、后期可被Lambda替代。
2.2 基础无状态仿函数
#include<iostream>
#include<string>
using namespace std;
// 自定义仿函数类
class F {
public:
void operator() (const string &info) const{
cout << "info:"<<info << endl;
}
};
int main() {
F f;
f("hello world"); // 像函数一样调用
return 0;
}
2.3 一元/二元 带状态仿函数
#include<iostream>
using namespace std;
class Add1 {
public:
Add1() { v = 0; }
Add1(int v) :v(v) {}
// 二元仿函数
int operator() (int a, int b) const {
return a + b;
}
// 一元仿函数
int operator() (int a) const {
return a + v;
}
private:
int v;
};
int main() {
Add1 add1(100);
cout << add1(10, 20) << endl;
cout << add1(10) << endl;
Add1 add(0);
cout<<add(10)<<endl;
cout<<add(20)<<endl;
cout<< add(30)<<endl;
return 0;
}
2.4 谓词仿函数(返回bool)
谓词:仿函数返回值为bool类型,分为一元谓词、二元谓词,多用于STL算法判断条件。
#include<iostream>
using namespace std;
// 二元谓词:a >= b
class GreaterEqual {
public:
bool operator() (int a, int b) const {
return a >= b;
}
};
// 一元谓词:取反
class Not {
public:
bool operator() (bool b) const {
return !b;
}
};
int main() {
GreaterEqual ge;
Not _not;
cout << boolalpha<<ge(10, 20) << endl;
cout << boolalpha<<_not(ge(10, 20)) << endl;
return 0;
}
2.5 STL 内置仿函数(头文件 <functional>)
STL内置大量现成仿函数,无需自己手写,可直接配合算法、bind使用。
分类:算术运算、关系运算、逻辑运算、位运算
#include<iostream>
#include<functional>
using namespace std;
int main() {
// 算术仿函数
multiplies<int> mul;
cout << mul(10, 20) << endl;
plus<int> p;
cout << p(10, 20) << endl;
minus<int> m;
cout << m(10, 20) << endl;
divides<int> d;
cout << d(10, 20) << endl;
modulus<int> mod;
cout << mod(10, 20) << endl;
negate<int> ne;
cout << ne(10) << endl;
// 关系仿函数
not_equal_to<int> neq;
cout<< neq(10,20)<<endl;
// 自动推导类型
less<> f2;
cout<<f2(10,20)<<endl;
// 逻辑仿函数
logical_and<> f3;
cout<<f3(f2(3,2),f2(10,20))<<endl;
return 0;
}
三、Lambda表达式(重点,替代仿函数)
3.1 核心作用
定义匿名函数,替代繁琐的自定义仿函数,写法简洁、适合临时逻辑、配合STL算法使用。
3.2 标准语法
[捕获列表](参数列表) mutable -> 返回值类型 { 函数体 }
捕获规则
-
[]:不捕获任何变量 -
[=]:值捕获所有局部变量(只读) -
[&]:引用捕获所有局部变量(可修改原变量) -
[a,b]:值捕获指定变量 -
[&a]:引用捕获指定变量 -
mutable:允许修改值捕获的副本变量
3.3 基础Lambda使用
#include<iostream>
using namespace std;
int main() {
// 二元加法Lambda
auto _plus_f = [](int a, int b) ->int { return a + b; };
cout<< _plus_f(10, 20) << endl;
// 二元比较谓词
auto gt_f = [](int a, int b)->bool {return a > b; };
cout<<boolalpha<< gt_f(10, 20) << endl;
// 一元输出
auto show_f = [](int v) { cout << v << endl; };
show_f(10);
// 无参匿名函数
auto hi = [] { cout << "hello lambda" << endl; };
hi();
return 0;
}
3.4 变量捕获 + mutable修改
#include<iostream>
using namespace std;
int main() {
int a =10, b = 5;
int* ap = &a;
// 值捕获 + mutable 允许修改副本
auto f = [a, b]() mutable{
cout<<"lambda a++ = " << ++a << endl;
cout << "lambda a+b = " << a+b << endl;
};
cout<< "main a = " << a << endl;
f();
cout<< "main a = " << a << endl;
// 值捕获指针:可修改指向内容
auto f1 = [=](int v) {
*ap += v;
};
f1(10);
cout << "main a = " << a << endl;
return 0;
}
四、bind 参数绑定器
4.1 核心作用
将多元仿函数降维(二元转一元),固定部分参数,剩余参数用占位符接收。
占位符:placeholders::_1、_2... 代表调用时传入的第N个参数。
4.2 实战代码
#include<iostream>
#include<functional>
using namespace std;
int main() {
plus<> _add;
cout << _add(10, 20) << endl;
// 固定第一个参数10,二元降一元
auto _add1 = bind(_add, 10, placeholders::_1);
cout << _add1(20) << endl;
// 固定第二个参数20
auto _add2 = bind(_add, placeholders::_1, 20);
cout << _add2(30) << endl;
return 0;
}
五、STL 常用算法(核心重点)
头文件:<algorithm> <functional> <iterator>
5.1 遍历算法 for_each
#include<iostream>
#include<vector>
#include<deque>
#include<list>
#include<map>
#include<algorithm>
using namespace std;
// 重载输出,适配所有容器
ostream& operator<<(ostream& out, deque<int>& v) {
for_each(v.begin(), v.end(), [](int item) {
cout<<item<<" ";
});
cout << endl;
return out;
}
ostream& operator<<(ostream& out, list<int>& v) {
for_each(v.begin(), v.end(), [](int item) {
cout << item << " ";
});
cout << endl;
return out;
}
ostream& operator<<(ostream& out, vector<int>& v) {
for_each(v.begin(), v.end(), [](int item) {
cout << item << " ";
});
cout << endl;
return out;
}
ostream& operator<<(ostream& out, map<int, int>& v) {
for_each(v.begin(), v.end(), [](pair<int, int> item) {
cout << item.first << " " << item.second << " ";
});
cout << endl;
return out;
}
int main() {
vector<int > v{ 9,1,2,4,8,2,3,3,9,5,4,1 };
cout << v;
deque<int> d{ v.begin(),v.end()};
cout<< d;
list<int> l{ v.begin(),v.end() };
cout << l;
map<int, int> m{ {1,2},{3,4},{5,6} };
cout << m;
return 0;
}
5.2 查找算法 find / find_if
#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
#include<ctime>
using namespace std;
// 生成随机数
void genRandom(vector<int>& v, int len, int _min, int _max) {
srand(time(NULL));
v.clear();
for (int i = 0; i < len; i++) {
v.push_back(rand() % (_max - _min+1) + _min);
}
}
int main() {
vector<int> v;
genRandom(v, 10, 1, 100);
for_each(v.begin(), v.end(), [](int item) {cout << item<<" "; });
cout << endl;
// 精准查找
vector<int>::iterator it=find(v.begin(), v.end(), 90);
if (it != v.end()) {
cout << "精准查找:OK" << endl;
}
else {
cout<< "精准查找:NO" << endl;
}
// 条件查找:找第一个小于50的数
auto it2 = find_if(v.begin(), v.end(), bind(less<>(),placeholders::_1,50));
if (it2 != v.end()) {
cout<< "条件查找:OK" << endl;
}
else {
cout << "条件查找:NO" << endl;
}
return 0;
}
5.3 子序列搜索 search
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
int main() {
vector<int> v1{ 3,8,7,2,1,3,4,5,6 };
vector<int> v2{ 1,2,3,5 };
auto it = search(v1.begin(), v1.end(), v2.begin(), v2.end());
if (it != v1.end())
{
cout<< "容器子序列匹配:OK" << endl;
}
else {
cout << "容器子序列匹配:NO" << endl;
}
// 字符串子串查找
string s1 = "hi,disen";
string s2 = "disen";
auto it2 = search(s1.begin(), s1.end(), s2.begin(), s2.end());
if (it2 != s1.end())
{
cout << "字符串子串匹配:OK" << endl;
}
else {
cout << "字符串子串匹配:NO" << endl;
}
return 0;
}
5.4 count_if 条件统计
#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
#include<ctime>
using namespace std;
void genRandom(vector<int>& v, int len, int _min, int _max) {
srand(time(NULL));
v.clear();
for (int i = 0; i < len; i++) {
v.push_back(rand() % (_max - _min + 1) + _min);
}
}
int main() {
vector<int> v;
genRandom(v, 10, 1, 100);
// 统计小于50的元素个数
int cnt = count_if(v.begin(),v.end(),bind(less<>(),placeholders::_1,50));
cout << "小于50的元素个数:" << cnt << endl;
return 0;
}
5.5 copy_if / transform 复制与变换
#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
#include<iterator>
#include<ctime>
using namespace std;
void genRandom(vector<int>& v, int len, int _min, int _max) {
srand(time(NULL));
v.clear();
for (int i = 0; i < len; i++) {
v.push_back(rand() % (_max - _min + 1) + _min);
}
}
int main() {
vector<int> v;
genRandom(v, 10, 1, 100);
vector<int> v2;
// copy_if:复制大于等于70的元素
copy_if(v.begin(),v.end(),back_inserter(v2), bind(greater_equal<int>(), placeholders::_1, 70));
for_each(v2.begin(), v2.end(), [](int item) {cout << item << " "; });
cout << endl;
// transform:元素转换映射
vector<bool> flags;
transform(v.begin(), v.end(), back_inserter(flags), [](int v)->bool{return v > 90; });
return 0;
}
5.6 综合练习:字符串处理
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<functional>
#include<iterator>
using namespace std;
int main() {
vector<string> v{ "hello","world","disen","cpp","java","c++","c#","python","php" };
vector<string> v2;
vector<int> v3;
vector<pair<string,int>> v4;
// 筛选长度大于3的字符串
copy_if(v.begin(), v.end(), back_inserter(v2), bind([](string a, int size) {return a.size() > size; }, placeholders::_1, 3));
for_each(v2.begin(),v2.end(), [](string item) {cout << item << " "; });
cout << endl;
// 转换为字符串长度
transform(v.begin(),v.end(),back_inserter(v3), [](string item)->int {return item.size(); });
for_each(v3.begin(), v3.end(), [](int item) {cout << item << " "; });
cout << endl;
// 转换为pair数组
transform(v.begin(), v.end(), back_inserter(v4), [](string item)->pair<string, int> {
pair<string, int> p(item, item.size());
return p; });
for_each(v4.begin(), v4.end(), [](pair<string, int> item) {cout << item.first << " " << item.second << " "; });
cout << endl;
return 0;
}
六、核心总结
-
bitset:固定长度位图,高效位运算、权限判断、进制转换
-
仿函数:重载()的类对象,可存状态,分一元/二元/谓词,可被Lambda替代
-
Lambda:匿名函数,捕获外部变量,mutable修改值捕获副本,简洁适配STL算法
-
bind绑定器:多元函数降维,固定参数+占位符传参
-
STL算法:for_each遍历、find查找、search子序列、count_if统计、copy_if复制、transform元素转换
-
所有算法均配合 仿函数/bind/lambda 实现自定义条件,是STL核心精髓
更多推荐

所有评论(0)