09_STL包括容器(containers)、迭代器(iterators)、空间配置器(allocator)、配接器(adapters)、算法(algorithms)、仿函数六个部分
来源:互联网 发布:jcl外国语学院知乎 编辑:程序博客网 时间:2024/05/16 06:31
- 目录
- 一STL
- 二容器containers 与 迭代器iterators
- 三算法algorithms
- 四GPU编程
【目录】
一、 STL : 2
1、 简介: 2
2、 分类: 2
3、 例子: 2
二、 容器(containers) 与 迭代器(iterators) 3
1、 序列容器: 3
2、 关联容器: 3
3、 Vectors (数组) 3
4、 List(双向链表) 4
5、 Set(链式结构)-红黑树容器 7
6、 Multiset 9
7、 映射map 12
8、 Multimap 13
9、 Hashset 14
10、 Hashmap 15
11、 堆stack 16
12、 queue队列 17
13、 Deque双端队列: 18
14、 Priority_queue (堆)最高优先级元素总是第一个出列 19
15、 Bitset位集合 20
16、 字符串string 22
三、 算法(algorithms) 24
1、 Find 与 for_each 例子: 24
2、 Find_if 例子: 25
3、 lambda表达式 26
4、 Fill例子: 30
5、 Count,统计例子: 31
6、 adjacent_find 查找相同一组的元素: 31
7、 random_shuffle 打乱数据: 32
8、 Partition 分区无序 , rotate转换: 32
9、 prev_permutation 自动排序并且可以显示: 33
10、 Sort 排序: 33
11、 partial_sort 部分排序 : 34
四、 GPU编程 34
1、 Hello 34
2、 35
一、STL :
1、简介:
①.STL ( Standard Template Library),标准模板库;
②.STL现在是C++的一部分,因此不用额外安装什么;
③.STL被内建在你的编译系统之内;
④.在C++标准中,STL被组织为下面的17个头文件:<algorithm>、<deque>、<functional>、<iterator>、<array>、<vector>、<list>、<forward_list>、<map>、<unordered_map>、<memory>、<numeric>、<queue>、<set>、<unordered_set>、<stack>和<utility>。
2、分类:
①.容器(containers)、
②.迭代器(iterators)、
③.空间配置器(allocator)、
④.配接器(adapters)、
⑤.算法(algorithms)、
⑥.仿函数(functors)六个部分
3、例子:
#include<iostream>#include <vector>//容器#include<array>//数组#include <algorithm>//算法using namespace std;/*实现一个类模板,专门实现打印的功能*/template<class T> //类模板实现了方法class myvectorprint{public: void operator ()(const T &t)//重载,使用(),打印 { std::cout << t << std::endl; }};void main(){ vector<int> myvector; myvector.push_back(11); myvector.push_back(21); array<int, 10> myarray = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; myvectorprint<int >print;//对于打印进行实例化 //begin,endl迭代器,是一个指针,每一个指针指向的都是内容的实体,所以可以直接通过*p打印出来内容。 for_each (myvector.begin(), myvector.end(),print); for_each(myarray.begin(), myarray.end(), print); cin.get(); //算法可以适用于任何容器,for_each是一个算法(这里foreach实现的是一个函数包装器的功能,可以查看下源码)}
二、容器(containers) 与 迭代器(iterators)
1、序列容器:
①.每个元素都有固定位置,这取决于插入时机和地点,与元素值无关。例如:list , vector , deque ……
2、关联容器:
①.每个元素位置取决于特定的排序准则,和插入顺序无关。例如:set , multiset , map , multimap……
3、Vectors (数组)
①.内部数据结构:数组。
②.在堆上开辟空间。
③.随机访问每个元素,所需要的时间为常量。
④.在末尾增加或删除元素所需时间与元素数目无关,在中间或开头增加或删除元素所需时间随元素数目呈线性变化。
⑤.可动态增加或减少元素,内存管理自动完成,但程序员可以使用reserve()成员函数来管理内存。
⑥.vector的迭代器在内存重新分配时将失效(它所指向的元素在该操作的前后不再相同)。当把超过capacity()-size()个元素插入vector中时,内存会重新分配,所有的迭代器都将失效;否则,指向当前元素以后的任何元素的迭代器都将失效。当删除元素时,指向被删除元素以后的任何元素的迭代器都将失效。
⑦.例子:
#include<iostream>#include<vector>#include <array>#include <tuple>using namespace std;void main1(){ array<int, 5>myarray = { 1, 2, 3, 4, 5 }; //数组,静态数组,栈上 vector <int >myvetor; myvetor.push_back(1); //动态数组,堆上, //不需要变长,容量较小,array //需要变长,容量较大,vetor}
4、List(双向链表)
①.内部数据结构:双向环状链表。
②.不能随机访问一个元素。
③.可双向遍历。
④.在开头、末尾和中间任何地方增加或删除元素所需时间都为常量。
⑤.可动态增加或减少元素,内存管理自动完成。
⑥.增加任何元素都不会使迭代器失效。删除元素时,除了指向当前被删除元素的迭代器外,其它迭代器都不会失效。
⑦.例子:
#include<iostream>#include <hash_set>#include <list>#include<stdio.h>//list适用于经常插入,经常删除using namespace std;void main(){ list<int> mylist; mylist.push_back(1); mylist.push_back(2); mylist.push_back(3); mylist.push_back(4); //mylist[1];错误链表是没下标的,必须使用迭代器 auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist.end(); //list用迭代器进行遍历 for (;ibegin!=iend;ibegin++) { cout << *ibegin << endl; printf("%p,%p\n", ibegin._Ptr , ibegin);//重载 } cin.get();}//list删除void main3(){ list<int> mylist; mylist.push_back(1); mylist.push_back(2); mylist.push_back(3); mylist.push_back(4); mylist.push_back(5); //auto i = mylist.begin();//删除元素,依赖于迭代器, //++i; auto i = mylist.end();//end最后一个没有实体, i--; mylist.erase(i);//链式存储,不允许下标访问 //只能用迭代器,链表迭代器只能用++,-- //mylist.clear();清空 auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist.end(); for (; ibegin != iend; ibegin++) { if ((*ibegin) == 3) { mylist.erase(ibegin);//删除,删除的时候迭代器会发生 break;(注意:这里删除之后迭代器发生了变化,如果没有break的话这里会产生错误。迭代器必须重新赋值) } //cout << *ibegin << endl; } { auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist.end(); for (; ibegin != iend; ibegin++) { cout << *ibegin << endl; } } cin.get();}void main4(){ int a[5] = { 1, 2, 3, 4, 5 }; list<int > mylist(a, a + 5);//根据数组初始化, //传递开始地址,传递结束地址 // mylist(0);不行 //mylist[1];不行,只能用迭代器访问 mylist.push_back(10); mylist.push_front(12); auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist.end(); for (; ibegin != iend; ibegin++) { if (*ibegin==3) { mylist.insert(ibegin ,30); break;//删除或者插入,迭代器都会发生变化 } } mylist.remove(30);//直接一个函数,根据元素来删除 cin.get( ) ;}/*反向迭代器*/void main5(){ int a[5] = { 1, 2, 3, 4, 5 }; list<int > mylist(a, a + 5);//根据数组初始化, auto rb = mylist.rbegin(); auto re = mylist.rend(); //同时正向与方向查找 for (;rb != re; rb++) { cout << *rb << endl; } cin.get();}/*list链表合并*/void main6(){ int a[5] = { 1, 2, 3, 104, 5 }; list<int > mylist1(a, a + 5);//根据数组初始化, int b[5] = { 11, 122,33, 44, 55 }; list<int > mylist2(b, b + 5);//根据数组初始化, mylist1.sort(); mylist2.sort();//排序 mylist1.merge(mylist2);//合并之前必须有序 { auto ibegin = mylist1.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist1.end(); for (; ibegin != iend; ibegin++) { cout << *ibegin << endl; } } cout << "\n\n\n"; { auto ibegin = mylist2.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist2.end(); for (; ibegin != iend; ibegin++) { cout << *ibegin << endl; } } cin.get();}/*list唯一*/void main7(){ int a[6] = { 1, 2,98, 2, 5, 98 }; list<int > mylist1(a, a + 6);//根据数组初始化, { auto ibegin = mylist1.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist1.end(); for (; ibegin != iend; ibegin++) { cout << *ibegin << endl; } } mylist1.sort(); mylist1.unique();//唯一依赖于排序 cout << "\n\n\n"; { auto ibegin = mylist1.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist1.end(); for (; ibegin != iend; ibegin++) { cout << *ibegin << endl; } } cin.get();}
5、Set(链式结构)-红黑树容器
①.按照键进行排序存储,值必须可以进行比较,可以理解为set就是键和值相等的map键唯一。
②.元素默认按升序排列。
③.如果迭代器所指向的元素被删除,则该迭代器失效。其它任何增加、删除元素的操作都不会使迭代器失效。
④.例子:
#include<iostream>#include <set>using namespace std;void main1231(){ set<int>myset; myset.insert(10);插入 myset.insert(9); myset.insert(8); myset.insert(7); myset.insert(5); myset.insert(6); myset.insert(7); //myset.insert(7);重复会被舍弃 auto findpos = myset.find(10);查找 cout << " find ->" << *findpos << " \n"; auto ib = myset.begin(); auto ie = myset.end(); for (;ib!=ie;ib++) { cout << *ib << " "; } std::cout << "\n"<<myset.size() << endl; cin.get();}
⑤.高级:
#include<iostream>#include <set>#include <string>#include <bitset>using namespace std;struct strless{ bool operator()(const char *str1, const char *str2) //二分查找法依赖于有序,字符串有序 { return strcmp(str1, str2) < 0; }};//红黑树,处理纯数字非常少,处理类对象以及字符串void main1(){ const char *cmd[] = { "abc", "calc", "notepad", "const","xyz","ghj" }; set< const char *, strless> myset(cmd, cmd + 6, strless());//构造 myset.insert("1234"); myset.insert("4567"); 添加 //pair起到获取插入返回值,第一个类型,类型比大小的方式(己:就是将插入值所在的节点【二叉树上值所对应的节点】返回,) pair<set<const char *>::iterator, bool> p = myset.insert("9876"); cout << "pair start" << endl; cout << *(p.first) <<" "<< p.second << endl; cout << "pair over" << endl; auto ib = myset.begin(); auto ie = myset.end(); for (;ib!=ie;ib++) { cout << *ib << endl; } set<const char *, strless>::iterator pfind = myset.find("xyz");//查找 std::cout <<"\n\n\n"<< *pfind << endl; cin.get();}
6、Multiset
①.键可以不唯一。(己:相同元素在二叉树上的同个节点,以链表的形式存储)
②.其它特点与map相同。
③.例子:
#include<iostream>#include <set>#include <stdio.h>#include <list>#include <vector>#include <algorithm>#include <functional>using namespace std;void main12(){ multiset <int>myset; myset.insert(11); myset.insert(12); myset.insert(13); myset.insert(10); myset.insert(10); myset.insert(100); auto ib = myset.begin(); auto ie = myset.end(); for (;ib!=ie;ib++) { std::cout << *ib << std::endl; printf("%p,%p\n", ib, ib._Ptr);//智能指针 } cin.get();}/*智能指针讲解list*/void main(){ list<int> mylist; mylist.push_back(11); mylist.push_back(1); mylist.push_back(16); mylist.push_back(1); mylist.push_back(18); auto ib = mylist.begin(); auto ie = mylist.end(); for (;ib!=ie;ib++) { std::cout << *ib << std::endl; printf("%p\n", ib); printf("%p\n", ib._Ptr); //智能指针 STL bug ,分行打印,先访问内部,再访问外部(注意:) printf("%p,%p\n", ib._Ptr,ib );//智能指针. } cin.get();}/*智能指针讲解list*/void mainx(){ list<int> mylist; mylist.push_back(1); mylist.push_back(2); mylist.push_back(3); mylist.push_back(4); //mylist[1]; auto ibegin = mylist.begin();//指针,指向一个迭代器,迭代器存储了位置 auto iend = mylist.end(); //list用迭代器进行遍历 for (; ibegin != iend; ibegin++) { cout << *ibegin << endl; printf("%p,%p\n", ibegin._Ptr, ibegin);//重载 } cin.get();}/*find_if greater , bindlst */bool less3(int x){ return x < 3;}void mainu(){ vector<int> mylist; mylist.push_back(1); mylist.push_back(2); mylist.push_back(16); mylist.push_back(1); mylist.push_back(18); using namespace std; auto ib = mylist.begin(); auto ie = mylist.end(); for (; ib != ie; ib++) { std::cout << *ib << std::endl; } //仿函数可以实现一定的算法策略 auto ifind = find_if(mylist.begin(), mylist.end(), less3); // bind1st( greater<int>(), 3) //绑定一个函数, greater<int>(),3比三大的全部过滤掉 std::cout <<"\n\n\n\n"<< *ifind << endl; cin.get();}
④.高级:
#define _CRT_SECURE_NO_WARNINGS#include <set>#include <iostream>#include <string>//mutiset每一个节点都是一个链表,set每个节点就是一个节点using namespace std;struct student{ int id; char name[30];};//排序struct stuless{ bool operator()(const student &s1, const student &s2) { return s1.id < s2.id; }};void main2(){ student sarray[3] = { { 10, "tansheng" }, { 3, "liguilong" }, { 4, "xiongfei" } }; multiset<student, stuless> myset (sarray, sarray + 3, stuless()); student stu1; stu1.id = 20; strcpy(stu1.name, "mouzhiwei"); myset.insert(stu1); strcpy(stu1.name, "mouzhiwei1"); myset.insert(stu1); auto ib = myset.begin(); auto ie = myset.end(); for (;ib!=ie;ib++) { cout << (*ib).id << " " << (*ib).name << endl; } cin.get() ; }
⑤.补充(将相等的元素全部查找出来):
#include <set>#include <iostream>using namespace std;void mainA(){ multiset<int> myset; myset.insert(100); myset.insert(101); myset.insert(100); myset.insert(103); myset.insert(100); auto pfind = myset.find(101);找到第一个101 std::cout << *pfind << std::endl; auto allfind = myset.equal_range(100); //找到红黑树的链表节点,遍历所有的元素 //find链表的头结点,second最后一个空节点,遍历所有的元素 for (auto it = allfind.first; it != allfind.second;it++) { cout << *it << endl; } cin.get();}
7、映射map
#include <map>//也是红黑树#include <iostream>using namespace std;void main1111(){ map<const char * , int> mymap; mymap["司令"] = 10;//映射 ,对等的映射查找 mymap["军长"] = 9; mymap["师长"] = 8; mymap["旅长"] = 7; cout << mymap["司令"] << endl; cout << mymap["军长"] << endl; cout << mymap["师长"] << endl; cout << mymap["旅长"] << endl; std::cin.get();}struct student{ char * name; int year;};struct stuinfo{ int id; student stu;};void main3213(){ stuinfo infoarrary[] = { { 10, { "yincheng1", 21 } },{ 5, { "yincheng2", 22 } } , { 25, { "yincheng3", 30 } } }; map<int, student> m;//编号映射 结构体 for (int i = 0; i < 3;i++) { m[ infoarrary[i].id ] = infoarrary[i].stu;//编号映射一个学生的信息 } stuinfo infoarrarys = { 101, { "china", 99 } }; m[25] = infoarrarys.stu;//映射 map<int,student>::iterator ib = m.begin(); auto ie = m.end(); for (;ib!=ie;ib++) { cout << (*ib).first << endl; cout << (*ib).second.name <<" " <<(*ib).second.year << endl; } cin.get();}
8、Multimap
①.基本:
#include <map>#include <iostream>using namespace std;//map,mutlimap区别是map每一个节点是一个映射//multimap每一个一个节点是映射的链表的开头void main121321(){ map<const char *, int> m; m.insert(pair<const char *, int>("司令1",101)); m.insert(pair<const char *, int>("司令2", 102)); m.insert(pair<const char *, int>("司令3", 103)); m.insert(pair<const char *, int>("司令1", 104)); map<const char *, int>::iterator ib = m.begin(); auto ie = m.end(); for (; ib != ie; ib++) { cout << (*ib).first << " " << (*ib).second << "\n"; } cin.get();}void main2123123(){ multimap<const char *, int> m; m.insert(pair<const char *, int>("司令1", 101)); m.insert(pair<const char *, int>("司令2", 102)); m.insert(pair<const char *, int>("司令3", 103)); m.insert(pair<const char *, int>("司令1", 104)); auto ib = m.begin(); auto ie = m.end(); for (; ib != ie; ib++) { cout << (*ib).first << " " << (*ib).second << "\n"; } cin.get();}
②.补充:
#include <iostream>#include <map>#include <string>using namespace std;void main2(){ multimap<string, string> mymap; mymap.insert(pair<string, string>("yincheng", "a")); mymap.insert(pair<string, string>("yincheng1", "b")); mymap.insert(pair<string, string>("yincheng", "c")); mymap.insert(pair<string, string>("yincheng", "d")); auto ib = mymap.begin(); auto ie = mymap.end(); for (;ib!=ie;ib++) { cout << (*ib).first << " "<<(*ib).second << endl; } auto pfind = mymap.find("yincheng");//只找到相等元素的第一个 cout << "\n\n\n"; cout << (*pfind).first << " " << (*pfind).second<< endl; cout << "\n\n\n"; auto it = mymap.equal_range("yincheng");//从树节点吧关键字相同的链表全部拔下 //first起点,secondl链表最后的节点后面一个空节点,都是迭代器 for (auto i = it.first; i != it.second;i++) { cout << (*i).first << " " << (*i).second << endl; } cin.get(); cin.get();}
9、Hashset
#include <hash_set>#include <iostream>#include<algorithm>#include <string>using namespace std;void main123123123(){ const char *cmd[] = { "abc", "calc", "notepad", "const", "xyz", "ghj" }; hash_set<const char*> hs;//C++11自带了字符串的哈希,哈希有哈希表,查找方便快速 hs.insert("chian");添加 hs.insert("chi123an"); hs.insert("chi23an"); hs.insert("chzcian"); hs.insert("1chzcian"); auto pfind = hs.find("chi1213an");查找 if (pfind == hs.end()) { std::cout << "没有"; } else { std::cout << *pfind; } cin.get();}void main1asdasdsad(){ hash_set<int> hs; hs.insert(91); hs.insert(21); hs.insert(41); auto ib = hs.begin(); auto ie = hs.end(); for (;ib!=ie;ib++) { cout << *ib << endl; } auto pfind = hs.find(211); if (pfind==ie) { std::cout << "没有"; } else { std::cout << *pfind; } cin.get();}
10、Hashmap
#include <hash_map>//也是红黑树#include <iostream>#include<map>using namespace std;void main(){ map< int,const char *> m; m.insert(pair< int, const char *>(201, "司令1" )); m.insert(pair< int, const char *>(101, "司" )); m.insert(pair< int, const char *>(401, "司令11111" )); m.insert(pair< int, const char *>(301, "司令")); auto ib = m.begin(); auto ie = m.end(); for (; ib != ie; ib++) { cout << (*ib).first << " " << (*ib).second << "\n"; } { hash_map< int, const char *> m; m.insert(pair< int, const char *>(201, "司令1")); m.insert(pair< int, const char *>(101, "司")); m.insert(pair< int, const char *>(401, "司令11111")); m.insert(pair< int, const char *>(301, "司令")); auto ib = m.begin(); auto ie = m.end(); for (; ib != ie; ib++) { cout << (*ib).first << " " << (*ib).second << "\n"; } auto tofind = m.find(1101); if (tofind == ie) { cout << "没有找到"; } else { cout << "--"<<(*tofind).first<<"--"<<(*tofind).second; } } std::cin.get();}
11、堆stack
#include <stack>#include <iostream>using namespace std;void mainB(){ int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; stack<int> mystack; for (int i = 0; i < 10;i++) { mystack.push(a[i]); } while (!mystack.empty()) { int num = mystack.top(); std::cout << num << " "; mystack.pop(); } cin.get();}void mainA(){ int num; cin >> num; stack<int> mystack; for ( ;num;num/=2) { mystack.push(num % 2); std::cout << "当前元素个数" << mystack.size() << endl; } while (!mystack.empty()) { int num=mystack.top(); std::cout << num << " "; mystack.pop(); } cin.get(); cin.get();}
12、queue队列
#include <queue>#include <iostream>#include <string>#include <stdlib.h>#include <list>#include<deque>//双端队列//提供了二维动态数组的功能,头部,尾部,任意操作using namespace std;void mainX(){ queue<char *>myq; myq.push("calc"); myq.push("notepad"); myq.push("tasklist"); myq.push("mspaint"); while (!myq.empty()) { char *p= myq.front();//获取 system(p); myq.pop(); }}
13、Deque双端队列:
void mainY(){ deque<int> mydq; mydq.push_back(1); mydq.push_back(11); mydq.push_back(111); mydq.push_back(1111); mydq.push_back(11111); mydq.push_front(123); mydq.insert(mydq.begin() + 3, 100);//插入 for (int i = 0; i < mydq.size();i++) { std::cout << mydq[i] << std::endl; } auto ib = mydq.begin(); auto ie = mydq.end(); for (; ib != ie; ib++) { std::cout << *ib<< std::endl; } cin.get();}void main11(){ deque<int> mydq; mydq.push_back(1); mydq.push_back(11); mydq.push_back(111); mydq.push_back(1111); mydq.push_back(11111); mydq.push_front(123); //mydq.erase(mydq.begin()); //mydq.erase(mydq.end() - 1); mydq.pop_front();//头部弹出 mydq.pop_back();//尾部 //mydq.clear(); auto ib = mydq.begin(); auto ie = mydq.end(); for (; ib != ie; ib++) { std::cout << *ib << std::endl; } cin.get();}void main1234(){ deque<int> mydq1; mydq1.push_back(1); mydq1.push_back(11); mydq1.push_back(111); mydq1.push_back(1111); mydq1.push_back(11111); deque<int> mydq2; mydq2.push_back(2); mydq2.push_back(21); mydq2.push_back(211); mydq2.push_back(2111); mydq1.swap(mydq2);整体交换 { auto ib = mydq1.begin(); auto ie = mydq1.end(); for (; ib != ie; ib++) { std::cout << *ib << std::endl; } } { auto ib = mydq2.begin(); auto ie = mydq2.end(); for (; ib != ie; ib++) { std::cout << *ib << std::endl; } } cin.get();}void mainXF(){ deque<int> mydq1; mydq1.push_back(1); mydq1.push_back(11); mydq1.push_back(111); mydq1.push_back(1111); mydq1.push_back(11111); std::cout << mydq1.front() << std::endl;首元素 std::cout << mydq1.back() << std::endl; 尾元素 std::cout << mydq1.max_size() << std::endl; 最大装多少个 std::cout << mydq1.size() << std::endl; cin.get();}
14、Priority_queue (堆)最高优先级元素总是第一个出列
void mainRT(){ priority_queue<int > myq; myq.push(10); myq.push(12); myq.push(11); myq.push(110); myq.push(101);//自动排序 while (!myq.empty()) { std::cout << myq.top() << endl; myq.pop(); } cin.get();}struct student{ int age; string name;};//strcmp==0;struct stuless{ bool operator()(const student &s1, const student &s2) { return s1.age < s2.age; }};void main(){ //类名, //存储结构 //比大小函数 priority_queue<student, deque<student>, stuless> myq; student s1; s1.age = 10; s1.name = "谭胜"; student s2; s2.age = 9; s2.name = "熊飞"; student s3; s3.age = 19; s3.name = "熊peng飞"; myq.push(s1); myq.push(s2); myq.push(s3); while (!myq.empty()) { std::cout << myq.top().age << myq.top().name << endl; myq.pop(); } cin.get();}
15、Bitset位集合
#include <set>#include <bitset>#include <iostream>#include<string>using namespace std;/*正常打印*/void main3X(){ //8 位, (255)代表构造的数据 bitset<8>bs(255); for (int i = 0; i < 8;i++)//最高位存储i=7上 { cout << bs[i];/*这个是高位放高位*/ } cin.get(); cin.get();}/*反向打印*/void main3Y(){ //8 位, (215)代表构造的数据 bitset<8>bs(215); for (int i = 7; i >=0; i--) { cout << bs[i] << " " << ~bs[i] << endl; } cin.get(); cin.get();}/*float数的二进制*/void main3Z(){ float num = 1231231236.8; bitset<32> myset(num);/*32位*/ for (int i = 31; i >=0;i--) { cout << myset[i]; } cin.get();}/*将二进制位转化为string*/void main3S(){ int num =-5; bitset<32> myset(num); for (int i = 31; i >= 0; i--) { cout << myset[i]; } string str = myset.to_string(); cout <<"\n" <<str << endl; unsigned int data; data = myset.to_ulong();//补码 cout << "\n" << data<< endl; cin.get();}/*位操作方法*/void main345(){ bitset<8>bs(255); bs.set(7, 0);//操作二进制位 bs.set(0, 0); cout << bs.size() << endl;//位数 //bs.reset();//全部清零 //bs.none();//测试下是否有越位 for (int i = 7; i >=0; i--)//最高位存储i=7上 { cout << bs[i]; } cin.get();}
16、字符串string
#include<string>#include <iostream>#include <stdlib.h>using namespace std;//字符串初始化void main1s(){ char str[124] = "china is big"; //str = "12321";C写法,不能这样写,strcpy才行 //string str1(str); //str1 = "china is great"; string str1("ABCDEFG"); str1 = "china is china"; std::cout << str1; cin.get();}/*字符串连接*/void main2s(){ string str1("ABCD"); string str2("1234"); string str3 = str1 + str2;//重载了+操作符 std::cout << str3; char stra[12]="1231"; char strb[24]="2132"; //char strc[36] = stra + strb;不行,strcat才行 cin.get();}/*字符串的追加,+也能实现这个功能*/void main3s(){ string str1("ABCD"); string str2("1234"); str1.append(str2); str1 += str2;//字符串的增加 std::cout << str1; cin.get();}/*字符串插入*/void main4s(){ string str1("ABCD"); string str2("1234"); //任意位置插入字符 str1.insert(str1.begin(),'X'); /*字符串就想数组一样,可以采用下标的写法*/ str1.insert(str1.end(), 'X'); str1.insert(str1.begin()+3,3, 'X'); /*第三个位置插入三个字符x*/ std::cout << str1; cin.get();}/*字符串添加高级*/void main5s(){ string str1("12345678"); auto ib = str1.begin(); auto ie = str1.end(); for (;ib!=ie;ib++) { cout << *ib << endl; } //str1.erase(str1.begin());//删除一个字符 //str1.erase(str1.begin()+3,str1.end()-2); //删除这中间一连串的字符串 str1.erase(3, 4); //c从第三个字符开始删除四个字符 cout << str1 << endl; cin.get();}/*字符串替换*/void main6s(){ string str1("12345678china"); str1.replace(5, 3, "china");//从0到第三个字符替换为china //replace,1位置,长度,字符串 /*就是在第5(位置)之后的三个字符(原来字符串的长度),被替换为“china”(内容)*/ cout << str1 << endl; cin.get();}/*字符串查找*/void mainA1(){ string str("233锄禾日当午,谭胜把地雷买下土,谭胜来跳舞,炸成250"); //cout << (int)str.find("谭胜大爷") << endl; //int pos = str.find(","); //找到第一个皮配的,不匹配返回-1, //int pos = str.rfind("谭胜"); //尾部找到第一个皮配的,不匹配返回-1, cin.get();}/**/void mainA2(){ string str("ab123mn"); //int pos = str.find_first_of("123"); //find_firstof是第一个找到与字符串皮配字符位置 //int pos = str.find_first_not_of("abc"); //find_firstof是第一个找到与字符串不皮配字符位置 //int pos = str.find_last_of("123"); //find_firstof是最后一个找到与字符串皮配字符位置 int pos = str.find_last_not_of("123"); cout << pos << endl; cin.get();}/*判断是否相等*/void main1234(){ string str1 = "calc"; string str2 = "ABC1"; char strA[5] = "Asd"; char strB[5] = "Asd"; cout <<( str1 == str2) << endl;//重载了运算符 cout << (strA == strB) << endl;//比较地址,比较必须使用strcmp cout << str1.empty()<<endl;//是否为空 const char *p = str1.c_str(); system(p); cin.get();}/*反复查找*/void main(){ string str("abc is abc china is china"); //int pos = str.find('a', 0); //字符也一样,从0位置开始查找,pos是位置 //std::cout << pos << endl; 0 //pos = str.find('a', pos+1); 7 //std::cout << pos << endl; cin.get();}
三、算法(algorithms)
1、Find 与 for_each 例子:
#include <algorithm>#include <iostream>using namespace std;struct print{ void operator ()(int x)//重载了()符号,之后调用() { std::cout << x << endl; }};void printA(int x){ std::cout << x << endl;}void main1(){ int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int *p = find(a, a + 10, 8); std::cout << (void*)a << (void*)(a + 10) << std::endl; std::cout << *p << endl; std::cout << p << endl; if (p==(a+10)) { std::cout << "没有找到\n"; } for_each(a, a + 4, print());//遍历每一个元素, //printA是一个函数指针,必须是函数类型 cin.get();}void main1(){ vector<int> myv; myv.push_back(1); myv.push_back(2); myv.push_back(3); for_each(myv.begin(), myv.end(), [](int v){ cout << v << endl; }); auto i = find(myv.begin(), myv.end(), 23);如果没找到就返回end指针 if (i==myv.end()) { std::cout << "23玩失踪"; } else { std::cout <<*i; } cin.get();}
2、Find_if 例子:
void mainu(){ vector<int> mylist; mylist.push_back(1); mylist.push_back(2); mylist.push_back(16); mylist.push_back(1); mylist.push_back(18); using namespace std; auto ib = mylist.begin(); auto ie = mylist.end(); for (; ib != ie; ib++) { std::cout << *ib << std::endl; } //仿函数可以实现一定的算法策略 auto ifind = find_if(mylist.begin(), mylist.end(), less3); // less3 = bind1st( greater<int>(), 3) //绑定一个函数, greater<int>(),3比三大的全部过滤掉 std::cout <<"\n\n\n\n"<< *ifind << endl; cin.get();}void main2(){ vector<int> myv; myv.push_back(1); myv.push_back(2); myv.push_back(3); for_each(myv.begin(), myv.end(), [](int v){ cout << v << endl; }); //auto i = find_if(myv.begin(), myv.end(), [](int v)->bool{ return (v > 4); }); auto i = find_if_not(myv.begin(), myv.end(), [](int v)->bool{ return (v > 4); }); if (i == myv.end()) { std::cout << "玩失踪"; } else { std::cout << *i; } cin.get();}
3、lambda表达式
①.初级:
基本格式:【】(型参)->返回值{}
#include <iostream>#include <vector>#include <algorithm>#include <functional>using namespace std;template<class T> //模板类,实现对于某些容器元素的操作class add{public: void operator()( T &t)//重载()运算符,进行操作 { t *= 2; std::cout << t<<"\n"; }};void go(int a){ a *= 2; std::cout << a << "\n";}void main(){ vector<int> myv; myv.push_back(10); myv.push_back(9); myv.push_back(7); myv.push_back(9); add<int> addA;//省略, //for_each(myv.begin(), myv.end(), addA); //for_each(myv.begin(), myv.end(), add<int>()); //for_each(myv.begin(), myv.end(), go); /*函数包装器与类包装器*/ /*兰达表达式*/ auto fun = [](int a, int b){ return a + b; };//R表达式 auto funA = [](int a){a *= 2; cout << a << endl; }; cout << fun(1, 2) << endl; for_each(myv.begin(), myv.end(), funA); for_each(myv.begin(), myv.end(), [](int a){a *= 2; cout << a << endl; }); cin.get();}
②.高级:
#include <functional>#include <iostream>#include<vector>#include<algorithm>using namespace std;/*lambda表达式,带参数,无返回值*/void main1(){ auto fun1 = [](){cout << "hello china"; }; fun1(); auto fun2 = [](int a, int b){return a + b; }; cout << fun2(10, 9) << endl; std::cin.get();}/*lambda表达式结合算法for_each*/void main2(){ vector<int> myv; myv.push_back(1); myv.push_back(2); myv.push_back(11); auto fun1 = [](int v){ cout << v << endl; }; for_each(myv.begin(), myv.end(), fun1); /* for_each(myv.begin(), myv.end(), [](int v){cout << v << endl;}); */ std::cin.get();}/* [=](int v){ },引用外部变量,不能修改*/void main3(){ vector<int> myv; myv.push_back(1); myv.push_back(2); myv.push_back(11); int a = 10; // =知道a的存在,可以引用,只能读,不可以写,引用当前块语句内部的局部变量, auto fun1 = [=](int v){ v += a; cout << v << endl; }; for_each(myv.begin(), myv.end(), fun1); cout << a << endl; std::cin.get();}/*[&a](int v){ } : 引用变量a*/void main4(){ vector<int> myv; myv.push_back(1); myv.push_back(2); myv.push_back(11); int a = 10; //引用变量a, auto fun1 = [&a](int v){a = 3; v += a; cout << v << endl; }; for_each(myv.begin(), myv.end(), fun1); cout << a << endl; std::cin.get();}/*函数指针,函数调用*/void main5(){ [](){cout << "hello china"; };//是一个函数指针 [](){cout << "hello china"; }();//调用函数 cin.get();}/*类中的lambda表达式*/class test{public: vector<int> myv; int num;public: test() { num = 12; myv.push_back(10); myv.push_back(11); } void add() { int x = 3; //[]引用this //auto fun1 = [this,x](int v){ cout << v+x+this->num << endl; }; //=按照副本引用this,还有当前块语句局部变量,不可以赋值,但是可以读取 //&按照引用的方式操作局部变量,this,可以赋值,可以读取 //副本(拷贝)引用a,[=] [a] //引用 a [&] [&a] auto fun1 = [&](int v){ cout << v + x + this->num << endl; x = 3; }; for_each(this->myv.begin(), this->myv.end(), fun1); }};/*C++ 11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。Lambda的语法形式如下:[函数对象参数](操作符重载函数参数) mutable或exception声明->返回值类型{ 函数体 }可以看到,Lambda主要分为五个部分:[函数对象参数]、(操作符重载函数参数)、mutable或exception声明、->返回值类型、{ 函数体 }。下面分别进行介绍。一、[函数对象参数],标识一个Lambda的开始,这部分必须存在,不能省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。函数对象参数只能使用那些到定义Lambda为止时Lambda所在作用范围内可见的局部变量(包括Lambda所在类的this)。函数对象参数有以下形式:1、空。没有使用任何函数对象参数。2、 = 。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。3、&。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。4、this。函数体内可以使用Lambda所在类中的成员变量。5、a。将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符。6、&a。将a按引用进行传递。7、a, &b。将a按值进行传递,b按引用进行传递。8、 = ,&a, &b。除a和b按引用进行传递外,其他参数都按值进行传递。9、&, a, b。除a和b按值进行传递外,其他参数都按引用进行传递。二、(操作符重载函数参数),标识重载的()操作符的参数,没有参数时,这部分可以省略。参数可以通过按值(如:(a, b))和按引用(如:(&a, &b))两种方式进行传递。三、mutable或exception声明,这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。exception声明用于指定函数抛出的异常,如抛出整数类型的异常,可以使用throw(int)。四、->返回值类型,标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。五、{ 函数体 },标识函数的实现,这部分不能省略,但函数体可以为空。/*lambda返回值*/void mainS (){ //double是返回值类型 auto fun1 = []()->double{cout << "hello china"; return 1; }; fun1(); auto fun2 = [](int a,double b)->decltype(a/b){cout << "hello china"; return a/b; }; /*decltype(a/b)获取表达式的类型*/ fun2(1,2.3);}/*mutable修改内部副本的值*/void main(){ int a = 10; auto fun1 = [a](int v)mutable->double{ v += a; cout << v << endl; a = 3; return 3; }; cout << a << endl; std::cin.get();}
4、Fill例子:
#include <iostream>#include <vector>#include <algorithm>#include <list>#include <set>#include <string>using namespace std;template <class T>class show{public: void operator ()(T &t) { cout << t << " "; }};void main3(){ list <int > list1; vector <int > v1; list1.push_back(121); list1.push_back(12); v1.push_back(121); v1.push_back(12); //sort(list1.begin(), list1.end());//排序 //sort(v1.begin(), v1.end());//排序,简单的排序 //算法依赖于数据结构(链式,线性),不同的数据结构,算法不一样 fill(v1.begin() + 3, v1.end(), 3);//填充,指定位置数据进行初始化 /**/ for_each(list1.begin(), list1.end(), show<int>()); cout << "\n"; for_each(v1.begin(), v1.end(), show<int>()); cin.get();}
5、Count,统计例子:
void main4(){ multiset<int > myset; myset.insert(3); myset.insert(1); myset.insert(2); myset.insert(1); int i = 0; for (auto ib = myset.begin(), ie = myset.end(); ib != ie;ib++,i++) { } cout << i << endl; int num = count(myset.begin(), myset.end(), 1);//统计多少个节点 cout << num<< endl; cin.get();}
6、adjacent_find 查找相同一组的元素:
因为在multiset这红黑树上相同的元素会放在同个节点上,在同个节点上的相同元素按照链表排列。
void main5(){ multiset<int > myset; myset.insert(3); myset.insert(1); myset.insert(2); myset.insert(1); for_each(myset.begin(),myset.end(), show< const int>()); auto it= adjacent_find(myset.begin(), myset.end()); cout << "\n" << *it << endl; it++; cout << "\n" << *it << endl; it++; cout << "\n" << *it << endl; it++; cout << "\n" << *it << endl; it = adjacent_find(it, myset.end()); //查找相同的数据,可以自己确定位置 cout << "\n" << *it << endl; it++; cout << "\n" << *it << endl; cin.get();}
7、random_shuffle 打乱数据:
void main6(){ vector<int> v1; for (int i = 0; i < 10;i++) { v1.push_back(i); } for_each(v1.begin(), v1.end(), show<int>()); cout << "\n"; random_shuffle(v1.begin(), v1.end()); /*打乱原有的数据*/ for_each(v1.begin(), v1.end(), show<int>()); cout << "\n"; random_shuffle(v1.begin(), v1.end()); for_each(v1.begin(), v1.end(), show<int>()); cout << "\n"; random_shuffle(v1.begin(), v1.end()); for_each(v1.begin(), v1.end(), show<int>()); cin.get();}
8、Partition 分区无序 , rotate转换:
bool isok(int num){ return (num == 8);}void main7(){ vector<int> v1; for (int i =10; i>0; i--) { v1.push_back(i); } for_each(v1.begin(), v1.end(), show<int>()); //partition(v1.begin(), v1.end(), isok); /*服务于快速排序法的分区,根据最后一个函数包装器,将数据分区,这里将数据分为两个区,8是分界线*/ rotate(v1.begin(), v1.begin()+8, v1.end()); //v1.begin(), v1.begin()+8之间的数据移动到后面 cout << "\n"; for_each(v1.begin(), v1.end(), show<int>()); /* rotate(v1.begin(), v1.begin()+1, v1.end()); cout << "\n"; for_each(v1.begin(), v1.end(), show<int>()); rotate(v1.begin(), v1.begin() + 1, v1.end()); cout << "\n"; for_each(v1.begin(), v1.end(), show<int>()); rotate(v1.begin(), v1.begin() + 1, v1.end()); cout << "\n"; for_each(v1.begin(), v1.end(), show<int>()); */ cin.get();}bool isokN(int num){ return (num >12);}void main9(){ vector<int> v1; v1.push_back(11); v1.push_back(8); v1.push_back(12); for_each(v1.begin(), v1.end(), show<int>()); partition(v1.begin(), v1.end(), isokN); //分块划分,不要求有序 cout << "\n"; for_each(v1.begin(), v1.end(), show<int>()); cin.get();}
9、prev_permutation 自动排序并且可以显示:
void main8(){ int a[4] = { 2, 1, 3 ,10}; do { cout << a[0] << " " << a[1] << " " << a[2] <<a[3]<< "\n"; } while (prev_permutation(a,a+4));//排序并显示步骤 cin.get();}
10、Sort 排序:
void main10(){ vector<char>one; one.push_back('B'); one.push_back('A'); one.push_back('C'); for_each(one.begin(), one.end(), show<char>()); //sort(one.begin(), one.begin() + 3); sort(one.begin(), one.begin() + 3); 对前三个排序 cout << "\n"; for_each(one.begin(), one.end(), show<char>()); cin.get();}
11、partial_sort 部分排序 :
class student{public: string name; int score;public: student(string str, int num) :name(str), score(num) { } bool operator <(const student &s1)const { return this->score < s1.score; }};int main(){ vector<student> ss; { student s1("银城A", 106); ss.push_back(s1); } { student s1("银城B", 101); ss.push_back(s1); } { student s1("银城C", 103); ss.push_back(s1); } { student s1("银城D", 105); ss.push_back(s1); } partial_sort(ss.begin(), ss.begin() + 2,ss.end()); //将比较的结果中最小的两个排序,,部分排序 for (int i = 0; i < 4;i++) { std::cout << ss[i].name << ss[i].score << "\n"; } cin.get();}
四、GPU编程
1、Hello
#include <amp.h>#include <iostream>using namespace concurrency; using namespace std;void main(){ int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; array_view<int> av(10,a); //GPU计算结构,av存储到GPU显存,根据数组初始化 //=直接操作AV,(index<1>idx)操作每一个元素 //restrict (amp) 定位GPU执行 parallel_for_each(av.extent, [=](index<1>idx) restrict (amp) { av[idx] += 123; }); for (int i = 0; i < 10;i++) { std::cout << av[i] << endl; } cin.get();}
2、
- 09_STL包括容器(containers)、迭代器(iterators)、空间配置器(allocator)、配接器(adapters)、算法(algorithms)、仿函数六个部分
- 空间配置器allocator
- 空间配置器allocator
- STL:allocator空间配置器
- vector向量容器(containers)及迭代器(iterators)在其中的应用
- 容器配置器(allocator)(二)
- 配接器(包括仿函数),萃取器、分配器、迭代器
- 一个简单的空间配置器: allocator
- STL之空间配置器allocator
- 【STL】SGI空间配置器 Allocator
- stl之空间配置器Allocator
- STL(一):allocator 空间配置器
- Chapter 2:空间配置器 allocator
- STL-空间配置器(allocator)
- STL 空间配置器 allocator<一>
- 容器的allocator(容器配置器)(一)
- 仿函数functor和function adapters
- Boost.Interprocess使用手册翻译之八:分配器,容器和内存分配算法(Allocators, containers and memory allocation algorithms)
- MarkDow编辑器用法
- 网易构造队列
- [乐意黎原创]VSFTPD进行FTP连接时显示500 OOPS: cannot change directory:/ftp/private错误的解决方法
- 学会在博客中使用gif
- bit mask
- 09_STL包括容器(containers)、迭代器(iterators)、空间配置器(allocator)、配接器(adapters)、算法(algorithms)、仿函数六个部分
- android按两次返回退出程序
- java CAS
- Android Wi-Fi源码分析之WifiService操作Wi-Fi(一):分析Wifi.c中的wifi_load_driver()函数
- CSS3中不熟悉的属性2:display:box和display:flex的区别
- Linux下常用服务的端口号整理
- 关于线程池的理解
- CC2540、nRF51822应用开发比较
- React生命周期