【目录】
一、 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、