- c++里面的typedef和using
- 统计字符串中字符出现的次数
- map的find函数
- set有一定的查重功能,但是不能知道重复数据的个数
- lambda表达式的引入
- lambda表达式语法
- 捕获列表说明
map底层的实现是一个红黑二叉树 c++里面的typedef和using
typedef pair统计字符串中字符出现的次数value_type; using value_type=pair ; 二者等价 typedef int* PINT; using PINT=int *;
在map中[]运算符的重载的工能是访问或插入指定的元素”
emplateclass map { typedef pair<_Key, _Val> value_type; }; //T树 //哈希表 //map int main() {//统计字符串中字符出现的次数 string stra[] = { "map","duque","queue","vector","list","map","vector","map" }; std::map simap; // key-->value for (auto& x : stra) { simap[x] += 1; } std::map ::iterator it = simap.begin();//双向迭代器 for (; it != simap.end(); ++it) { cout << it->first << "==>" << it->second << endl; } return 0; }
#include//哈希表 template class map { typedef pair<_Key, _Val> value_type; }; //T树 //哈希表 //map int main() {//统计字符串中字符出现的次数 string stra[] = { "map","duque","queue","vector","list","map","vector","map" }; std::map simap;//底层是红黑树,通过string的字符顺序比较排序 // key-->value std::unordered_map unmap;//无序map 底层的实现是哈希表 for (auto& x : stra) { simap[x] += 1; unmap[x] += 1; } std::map ::iterator it = simap.begin(); for (; it != simap.end(); ++it) { cout << it->first << "==>" << it->second << endl; } std::unordered_map ::iterator uit=unmap.begin(); for (;uit!=unmap.end();++uit) { cout << uit->first << " " << uit->second << endl; } return 0; }
#include
#include
int main()
{
std::multimapanmap;//底层是红黑树,允许关键码重复,不支持[]运算符
std::mapnamap;//不允许关键码重复
//namap[23] = "yhping";
//namap[16] = "gg";
//namap[23] = "hello";
anmap.insert(map::value_type(23, "yhping"));
anmap.insert(map::value_type(16, "gg"));
//注意insert返回了一个键值对std::pair
anmap.insert(map::value_type(23, "hello"));
for (auto& x : anmap)
{
cout << x.first << " " << x.second << endl;
}
return 0;
}
#include
int main()
{
std::mapsimap;
simap["yhping"] = 12;
simap["bh"] = 23;
simap["mx"] = 18;
string name;
while (cin >> name, name != "end")
{
cout << simap[name] << endl;
}
return 0;
}
map的find函数
int main()
{
std::mapsimap;
simap["yhping"] = 12;
simap["ljl"] = 23;
simap["mx"] = 18;
std::map::iterator it = simap.find("ljl");
//从头到尾找一遍,找到就返回迭代器,没找到就返回end;
if (it != simap.end())
{
cout << it->first << " " << it->second << endl;
}
else
{
cout << "not key" << endl;
}
return 0;
}
set有一定的查重功能,但是不能知道重复数据的个数
int main()
{
std::setiset;
int x;
while (cin >> x, x != -1)
{
if (iset.count(x))
{
cout << "已经有了: " <
iset.insert(x);
}
}
return 0;
}
int main()
{
mapimap;
for (int i = 0; i < 1000; ++i)
{
int x = rand() % 1000;//ar;
imap[x] += 1;
}
return 0;
}
lambda表达式的引入
原有c++想要对数据集进行排序需要用std::sort()
#include#include #include using namespace std; void main() { int a[]={3,1,4,2,5}; int i; int len=sizeof(a)/sizeof(int);//这里切记要除以sizeof(int)! sort(a ,a + len, greater ()); //内置类型的由大到小排序 for(i=0;i ()); //内置类型的由小到大排序 for(i=0;i #include #includeint main() { int array[] = { 4,1,8,5,3,7,0,9,2,6 }; //默认排序是升序 sort(array,sizeof(array)/array[0]); //降序 sort(array,sizeof(array)/array[0],greater ()); return 0; } 如果待排序数的类型是自定义类型,则用户自己定义;排序时的比较规则
struct Goods { string _name; double _price; }; struct Compare { bool operator()(const Goods& gl, const Goods& gr) { return gl._price <= gr._price; } }; int main() { Goods gds[] = { { "苹果", 2.1 }, { "香蕉", 3.0 }, { "橙子", 2.2 }, {"菠萝", 1.5} }; sort(gds, gds + sizeof(gds) / sizeof(gds[0]), Compare()); return 0; }随着C++语法的发展,人们开始觉得上面的写法太复杂了,每次为了实现一个algorithm算法, 都要重新去写一个类,如果每次比较的逻辑不一样,还要去实现多个类,特别是相同类的命名,这些都给编程者带来了极大的不便。因此,在C++11语法中出现了lambda表达式。
int main() { Goods gds[] = { { "苹果", 2.1 }, { "相交", 3 }, { "橙子", 2.2 }, {"菠萝", 1.5} }; sort(gds, gds + sizeof(gds) / sizeof(gds[0]), [](const Goods& L, const Goods& R) ->bool { return L._price < R._price; }); return 0; }lambda表达式语法lambda表达式书写格式:
[capture-list] (parameters) mutable -> return-type {statement } ;[capture-list] :捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda函数使用。
(parameters):参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以连同()一起省略。
mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)。这里的const修饰的是[]里面获取的,不能修饰[]获取引用的,可以修饰[var]或[=]创建副本的
->return_type:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推导。
{statement}:函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量。
注意:
在lambda函数定义中,参数列表和返回值类型都是可选部分,而捕捉列表和函数体可以为空。因此C++11中最简单的lambda函数为:[]{};
该lambda函数不能做任何事情。int main() { // 最简单的lambda表达式, 该lambda表达式没有任何意义 [] {}; // 省略参数列表和返回值类型,返回值类型由编译器推导为int int a = 3, b = 4; [=] {return a + 3; }; // 省略了返回值类型,无返回值类型 auto fun1 = [&](int c) {b = a + c; }; fun1(10); cout << a << " " << b << endl; // 各部分都很完善的lambda函数 auto fun2 = [=, &b](int c)->int {return b += a + c;}; cout << fun2(10) << endl; // 复制捕捉x int x = 10; auto add_x = [x](int a)mutable{ x *= 2; return a + x;}; cout << add_x(10) << endl; return 0; }templatestruct my_plus { _Ty operator()(_Ty a,_Ty b)const { return a+b; } } int main() { auto f=[](int a,int b)-> int{return a+b;}; my_plus myi; myi(12,23); int x=f(12,23); cout< 通过上述例子可以看出,lambda表达式实际上可以理解为无名函数,该函数无法直接调用,如果想要直接调用,可借助auto将其赋值给一个变量。
int main() { auto f1= [](int a)->int {return a; }; //等价于 //auto f=[](int a) {return a;} auto f = [](int a) {return a + 1; }; //auto f = [](int a) {return { a,1 }; };//无法返回列表方案erro auto f2 = [](int a)->std::initializer_list捕获列表说明{return { a,1 }; };//返回列表方案 auto f3 = []() {return 1; }; return 0; } [] :
int g_max = 10; int add(int x, int y) { return x + y; } int fun() { int sum = 0; int num = 20; g_max = sum + num; //封闭函数局部变量不能在 lambda 体中引用,除非其位于捕获列表中 //auto f = [](int a)->int {return a + sum; };//erro auto f = [sum](int a)->int {return a +sum; }; auto f1 = [](int a)->int {return a + g_max; };//全局变量不需要捕获 return f1(10); } int main() { int a=fun(); cout << a << endl; return 0; }[var]:表示值传递方式捕捉变量var,会创建副本
void fun() { int x = 0; int y = 10; cout << &y << endl; //auto f = [y]()->int { y += 10; return y + 100; };//此时erro //此时y在lambda中只具备读的功能,也创建了副本; auto f = [y]()->int { cout << &y << endl; return y + 100; }; f(); cout <<&y<<" "<< y << endl; //创建副本 auto f1 = [y]()mutable->int {y += 10; cout << y << endl; return y + 100; }; f1(); cout << y << endl; } int main() { fun(); return 0; }int g_max = 10; int add(int x, int y) { return x + y; } int fun() { int sum = 0; int num = 20; g_max = sum + num; //封闭函数局部变量不能在 lambda 体中引用,除非其位于捕获列表中 //auto f = [](int a)->int {return a + sum; };//erro auto f3 = [sum](int a)mutable->int {cout << sum << endl; return a + sum; };// f3(0);//sum只能读 //auto f = [sum](int a)->int {sum += 10; return a + sum; };//erro //f(0); auto f = [sum](int a)mutable->int {sum += 10; cout << sum << endl;; return a + sum; }; f(0);//里面的sum修改的话只能创建副本,写时拷贝技术,范围只在在上述lambda中 cout << sum << endl; auto f1 = [](int a)->int {return a + g_max; }; return f1(10); } int main() { int a=fun(); cout << a << endl; return 0; }[=]:表示值传递方式捕获所有父作用域中的变量(包括this),创建副本
[&var]:表示引用传递捕捉变量var
int g_max = 10; int add(int x, int y) { return x + y; } int fun() { int sum = 0; int num = 20; g_max = sum + num; //封闭函数局部变量不能在 lambda 体中引用,除非其位于捕获列表中 //auto f = [](int a)->int {return a + sum; };//erro auto f3 = [sum](int a)mutable->int {cout << sum << endl; return a + sum; };// f3(0);//sum只能读 auto f = [&sum](int a)->int {sum += 10; return a + sum; };//这里相当于引用sum并不会重新创建sumf副本 f(0); cout << sum << endl; //auto f = [sum](int a)mutable->int {sum += 10; cout << sum << endl;; return a + sum; }; //f(0);//里面的sum修改的话只能创建副本,写时拷贝技术,范围只在在上述lambda中 //cout << sum << endl; auto f1 = [](int a)->int {return a + g_max; }; return f1(10); } int main() { int a=fun(); cout << a << endl; return 0; }[&]:表示引用传递捕捉所有父作用域中的所有变量(包括this)
int g_max = 10; int add(int x, int y) { return x + y; } int fun(int x) { int sum = 0; int num = 20; g_max = sum + num; //封闭函数局部变量不能在 lambda 体中引用,除非其位于捕获列表中 //auto f = [](int a)->int {return a + sum; };//erro //[&]在fun函数里面的局部变量可以直接在{}里面读,写 auto f=[&](int a)->int {x=a; sum+=10; num=a+x; return a+sum;}; return f(10); } int main() { int a=fun(100); cout << a << endl; return 0; }[this]:表示值传递方式捕捉当前的this指针,让lambda表达式拥有和当前类成员函数同样的访问权限。捕获this指针的目的是在lambda表达式中能够使用当前类的成员函数,和成员变量;



