C++

C++三种容器:list、vector和deque的区别:https://blog.csdn.net/gogokongyin/article/details/51178378

一、容器

小常识

1、queue、stack不可遍历,list迭代器不可以使用"it=it+1",而可以使用"it++"

2、我们为什么这样写循环?

for(vector<int>::iterator iter = xx.begin(); iter != xx.end(); ++ iter)
{
...
}

如果是一个空的list,这样写会报错么?不会,因为空容器的begin与end的返回值是相同的,进不了循环。但是,需要注意的是,他们不是空指针

std::vector::begin()

Returns an iterator to the first element of the container.

If the container is empty, the returned iterator will be equal to end().

std::vector::end()

Returns an iterator to the element following the last element of the container.

This element acts as a placeholder; attempting to access it results in undefined behavior.

3、erase()的写法

可以参考https://blog.csdn.net/sszgg2006/article/details/7453622

for(vector<int>::iterator it=vecInt.being(); it!=vecInt.end();){    //小括号里不需写 ++it
if(conditon){
it = vecInt.erase(it);
//以迭代器为参数,删除某元素及其迭代器并把数据删除后的下一个元素位置返回给迭代器。此时,不执行 //++it;
//这里it为实参,经转变为形参后,形参被删除,但是由于实参it是迭代器,是指针,所以实参it也成了野 //指针,所以需要重新赋值
}
else
{
++it;
}
}

此时,如果容器为空,erase()也没有没有问题。

1、vector

vector初始化

初始化方法

(1) vector ilist1;

默认初始化,vector为空, size为0,表明容器中没有元素,而且 capacity 也返回 0,意味着还没有分配内存空间。这种初始化方式适用于元素个数未知,需要在程序中动态添加的情况。

(2): vector ilist2(ilist);

vector ilist2 = ilist;

两种方式等价 ,ilist2 初始化为ilist 的拷贝,ilist必须与ilist2 类型相同,也就是同为int的vector类型,ilist2将具有和ilist相同的容量和元素

(3): vector ilist = {1,2,3.0,4,5,6,7};

vector ilist {1,2,3.0,4,5,6,7};

ilist 初始化为列表中元素的拷贝,列表中元素必须与ilist的元素类型相容,本例中必须是与整数类型相容的类型,整形会直接拷贝,其他类型会进行类型转换。

(4): vector ilist3(ilist.begin()+2,ilist.end()-1);

ilist3初始化为两个迭代器指定范围中元素的拷贝,范围中的元素类型必须与ilist3 的元素类型相容,在本例中ilist3被初始化为{3,4,5,6}。注意:由于只要求范围中的元素类型与待初始化的容器的元素类型相容,因此迭代器来自不同的容器是可能的,例如,用一个double的list的范围来初始化ilist3是可行的。另外由于构造函数只是读取范围中的元素进行拷贝,因此使用普通迭代器还是const迭代器来指出范围并没有区别。这种初始化方法特别适合于获取一个序列的子序列。

(5): vector ilist4(7);

默认值初始化,ilist4中将包含7个元素,每个元素进行缺省的值初始化,对于int,也就是被赋值为0,因此ilist4被初始化为包含7个0。当程序运行初期元素大致数量可预知,而元素的值需要动态获取的时候,可采用这种初始化方式。

(6):vector ilist5(7,3);

指定值初始化,ilist5被初始化为包含7个值为3的int


vector复制vector

实现从vector1复制到vector2,实验证明,四种方式都实现了内存上的复制

(1) vectorvector2(vector1);

(2) vectorvector3(vector1.begin(),vector1.end());

(3) vectorvector4=vector1;

(4) vectorvector5;

​ vector5.resize(vector1.size());

​ copy(vector1.begin(),vector1.end(),vector5.begin());

方法四,使用std::copy(),前一定对新的vector进行resize(),否则异常

vector使用案例

	vector<int>vector1 {1,2,3,4};
cout<<"元数据:"<<" ";
for_each(vector1.begin(),vector1.end(),[](int x){cout<<x<<" ";});
//构造函数(container)
vector<int>vector2(vector1);
reverse(vector2.begin(),vector2.end());
vector2[1]=111;
cout<<endl<<"构造函数(container): ";
for_each(vector2.begin(),vector2.end(),[](int x){cout<<x<<" ";});
cout<<"元数据:"<<" ";
for_each(vector1.begin(),vector1.end(),[](int x){cout<<x<<" ";});
//构造函数(container.begin(),container.end())
vector<int>vector3(vector1.begin(),vector1.end());
reverse(vector3.begin(),vector3.end());
vector3[1]=111;
cout<<endl<<"c.begin(),c.end(): ";
for_each(vector3.begin(),vector3.end(),[](int x){cout<<x<<" ";});
cout<<"元数据:"<<" ";
for_each(vector1.begin(),vector1.end(),[](int x){cout<<x<<" ";});
//赋值运算符重载=
vector<int>vector4=vector1;
reverse(vector4.begin(),vector4.end());
vector4[1]=111;
cout<<endl<<"赋值运算符重载= ";
for_each(vector4.begin(),vector4.end(),[](int x){cout<<x<<" ";});
cout<<"元数据:"<<" ";
for_each(vector1.begin(),vector1.end(),[](int x){cout<<x<<" ";});
//std::copy()
vector<int>vector5;
vector5.resize(vector1.size());
copy(vector1.begin(),vector1.end(),vector5.begin());
reverse(vector5.begin(),vector5.end());
vector5[1]=111;
cout<<endl<<"std::copy(): ";
for_each(vector5.begin(),vector5.end(),[](int x){cout<<x<<" ";});
cout<<"元数据:"<<" ";
for_each(vector1.begin(),vector1.end(),[](int x){cout<<x<<" ";});
/*
元数据: 1 2 3 4
构造函数(container): 4 111 2 1 元数据: 1 2 3 4
c.begin(),c.end(): 4 111 2 1 元数据: 1 2 3 4
赋值运算符重载= 4 111 2 1 元数据: 1 2 3 4
std::copy(): 4 111 2 1 元数据: 1 2 3 4
*/

vector的resize与reserve

reserve()函数为当前vector预留至少共容纳size个元素的空间.(译注:实际空间可能大于size)

resize() 函数( void resize( size_type size, TYPE val ) )改变当前vector的大小为size,且对新创建的元素赋值val

(翻译:

调整容器大小以包含count元素。

如果当前大小大于count,则容器将被缩减为其第一个count元素,就像重复调用pop_back()一样。

如果当前大小小于count,则附加元素并用值的副本初始化。)

resize和reserve函数本质都涉及了vector的内存存储空间,因为vector在内存中是连续存放的,所以当resize的空间大于现有的存储空间(capacity() 函数 返回当前vector在重新进行内存分配以前所能容纳的元素数量.)时,会重新选择更大的空间,并将所有元素复制过去。resize在初始化内存容量时有对值的初始化,所以此时push_back会产生size+1,内存容量不够,重新寻找更大的内存空间并复制所有元素,所以这个过程是很费事的。

插入测试

接下来探讨插入的效率的实例,分别尝试在插入大数据3.8GB和小数据380MB时,各种情况的实现。

(1)push_back直接插入

结论:费事,在插入的过程中,不断寻找“庇护所”,不断“迁移大本营”,舟车劳顿效率低下

void testPushBack_bigsize(){
vector<int> vector1;
clock_t start = clock();
for (int i = 0; i < 1000000000; ++i) {//3814MB
vector1.push_back(i);
}
cout <<"共耗时:"<< (clock() - start)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:42s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:1000000000 capacity:1073741824
clock_t start2 = clock();
vector1.push_back(1);
cout <<"共耗时:"<< (clock() - start2)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:0s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:1000000001 capacity:1073741824
}

(2)先reserve在push_back

结论:先分配空间再进行后续处理,能够有效的减少插入时间的损耗,耗时占原插入方式的1/3到1/2之间。

void testPushBack_byReserve_bigsize(){
vector<int> vector1;
vector1.reserve(1000000000);//3814MB
clock_t start = clock();
for (int i = 0; i < 1000000000; ++i) {
vector1.push_back(i);
}
cout <<"共耗时:"<< (clock() - start)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:17s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:1000000000 capacity:1000000000
clock_t start2 = clock();
vector1.push_back(1);
cout <<"共耗时:"<< (clock() - start2)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:76s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:1000000001 capacity:2000000000
}
void testPushBack_byReserve_smallsize(){
vector<int> vector1;
vector1.reserve(100000000);//381MB
clock_t start = clock();
for (int i = 0; i < 100000000; ++i) {
vector1.push_back(i);
}
cout <<"共耗时:"<< (clock() - start)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:1s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:100000000 capacity:100000000
clock_t start2 = clock();
vector1.push_back(1);
cout <<"共耗时:"<< (clock() - start2)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:2s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:100000001 capacity:200000000
}

(2)先resize在利用坐标进行赋值(相当于插入)

结论:在分配空间时直接对空间进行初始化,赋予初值,极大提升了存储的速率。但是在resize后进行push_back是不明智的选择。

void testinsert_byResize_bigsize(){
vector<int> vector1;
vector1.resize(1000000000);
clock_t start = clock();
for (int i = 0; i < 1000000000; ++i) {
vector1[i]=i;
}
cout <<"共耗时:"<< (clock() - start)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:3s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:1000000000 capacity:1000000000
clock_t start2 = clock();
vector1.push_back(1);
cout <<"共耗时:"<< (clock() - start2)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:66s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:1000000001 capacity:2000000000
}
void testinsert_byResize_smallsize(){
vector<int> vector1;
vector1.resize(100000000);
clock_t start = clock();
for (int i = 0; i < 100000000; ++i) {
vector1[i]=i;
}
cout <<"共耗时:"<< (clock() - start)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:0s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:size:10000000 capacity:10000000
clock_t start2 = clock();
vector1.push_back(1);
cout <<"共耗时:"<< (clock() - start2)/ CLOCKS_PER_SEC <<"s"<<endl;//共耗时:2s
cout <<"size:"<<vector1.size() << " capacity:" << vector1.capacity() << endl;//size:10000001 capacity:20000000
}

vector优化问题

防止reallocate内存,而导致的数据拷贝产生的额外耗时

vector在push_back的时候,如果空间不足,会自动增补一些空间,如果没有预留的空间可用

就直接申请另一块可用的连续的空间,把数据拷贝过去,然后删除旧空间,使用新空间

结果造成效率低下 。

可以通过以下两种组合来防止reallocate.

  1. vector::resize() 使用array index,效率最高,但是需要提前知道size大小

  2. vector::reserve()使用 push_back(),效率一般,较原生有一定提升。

3、hash_map

https://blog.csdn.net/yusiguyuan/article/details/12883727

hash函数->直接地址,比较函数->解决冲突

这两个参数刚好是我们在使用hash_map时需要指定的参数.

hash_map<int, string> mymap;

等同于:hash_map<int, string, hash, equal_to > mymap;

#include <hash_map>
#include <algorithm>
#include <iostream>
using namespace std; int main() {
__gnu_cxx::hash_map<int,string> mymap;
mymap[1]="风琴杨";
mymap[2]="林青霞";
if (mymap.find(1)!=mymap.end())
cout<<mymap[1]<<endl;
cout<<mymap[10]<<" null"<<endl;
return 0;
}
//output
/*
风琴杨
null
*/

4、map(treemap)

int main() {
string A ="anagram";
string B ="nagaram";
map<char,int> mymap1;
map<char,int> mymap2;
for (int i = 0; i < A.size(); ++i) {
mymap1[A[i]]++;
mymap2[B[i]]++;
}
bool flag = true;
//遍历一
for (int j = 0; j <min(mymap1.size(),mymap2.size()) ; ++j) {
int a = mymap1[A[j]];
int b = mymap2[A[j]];
if (a!=b){
flag= false;
break;
}
}
//遍历二
map<char,int>::iterator it2 = map2.begin();
for (map<char,int>::iterator it = map1.begin();it!=map1.end(),it2!=map2.end(); ++it,++it2) {
if(it->second!=it2->second||it->first!=it2->first){
flag=0;
break;
}
}
cout<<flag<<endl;
return 0;
}
//两数之和
int main() {
int nums[]{2, 7, 11, 15};
int target = 9;
map<int,int> mymap;
for (int i = 0; i < sizeof(nums)/ sizeof(nums[0]); ++i) {
if(mymap.find(target-nums[i])!=mymap.end()){
cout<<(*mymap.find(target-nums[i])).second<<" "<<i;
break;
}
else
mymap[nums[i]]=i;
}
return 0;
}

增删改查、multimap是一个key对应多个值

class student{
public:
int age;
string name;
string bjclass;
student(string _name,int _age, string _bjclass){
name = _name;
age = _age;
bjclass = _bjclass;
}
student(){}
}; void multimap_test(){
cout<<"---------------multimap--------------"<<endl;
student s1,s2,s3,s4,s5;
s1.name="s1";
s1.bjclass="se1161";
s2.name="s2";
s2.bjclass="se1161";
s3.name="s3";
s3.bjclass="se1162";
s4.name="s4";
s4.bjclass="se1162";
s5.name="s5";
s5.bjclass="se1162";
multimap<string,student> mymap2;
// 软件1161
mymap2.insert(make_pair("软件1161",s1));
mymap2.insert(make_pair("软件1161",s2));
mymap2.insert(make_pair("软件1161",s3));
// 软件1161
mymap2.insert(make_pair("软件1162",s4));
mymap2.insert(make_pair("软件1162",s5)); for (multimap<string,student>::iterator it =mymap2.begin(); it!=mymap2.end() ; ++it) {
cout<<it->first<<"\t"<<it->second.name<<endl;
} int se1161nums = mymap2.count("软件1161");
int se1162nums = mymap2.count("软件1162");
cout<<"软间1161人数:"<<se1161nums<<endl;
cout<<"软间1162人数:"<<se1162nums<<endl; //遍历所有软件1161的学生
multimap<string,student>::iterator it2 =mymap2.find("软件1161");
int flag = 0;
while (flag<se1161nums){
cout<<it2->first<<"\t"<<it2->second.name<<endl;
it2++;
flag++;
}
cout<<"----------修改测试------------\n";
//修改s3名称为ss3
for (multimap<string,student>::iterator it =mymap2.begin(); it!=mymap2.end() ; ++it) {
if(it->second.name=="s3")
it->second.name="ss3";
}
for (multimap<string,student>::iterator it =mymap2.begin(); it!=mymap2.end() ; ++it) {
cout<<it->first<<"\t"<<it->second.name<<"\t"<<it->second.bjclass<<endl;
}
}
int main() {
map<int,string> mymap1;
//插入方法1
pair<map<int,string>::iterator,bool> pair1 =mymap1.insert(pair<int,string>(1,"student1"));
if(pair1.second){
cout<<"key1插入成功\n";
} else
cout<<"key1插入失败\n"; mymap1.insert(pair<int,string>(2,"student2"));
//插入方法2
pair<map<int,string>::iterator,bool> pair2 = mymap1.insert(make_pair(1,"student3"));//若key已经存在则插入失败,返回pair的second为false
if(pair2.second){
cout<<"key2插入成功\n";
} else
cout<<"key2插入失败\n";
mymap1.insert(make_pair(4,"student4"));
//插入方法3
pair<map<int,string>::iterator,bool> pair3 = mymap1.insert(map<int,string>::value_type(5,"student5"));
if(pair3.second){
cout<<"key3插入成功\n";
} else
cout<<"key3插入失败\n";
mymap1.insert(map<int,string>::value_type(6,"student6"));
//插入方法4,若key已经存在会覆盖原值
mymap1[1]="student7";
mymap1[8]="student8";
for (map<int,string>::iterator it=mymap1.begin(); it !=mymap1.end() ; ++it) {
cout<<(*it).first<<":"<<(*it).second<<" ";
}
cout<<endl; cout<<"------------------查找测试------------------\n";
map<int,string>::iterator it = mymap1.find(4);
if (it!=mymap1.end())
cout<<"key:"<<it->first<<" value:"<<it->second<<endl;
else
cout<<"key4不存在!"<<endl; pair<map<int,string>::iterator,map<int,string>::iterator> pair4 = mymap1.equal_range(4);
cout<<"第一个迭代器的位置(>=4):"<<(*pair4.first).first<<"\t"<<(*pair4.first).second
<<" \n第二个迭代器的位置(>4):" <<(*pair4.second).first<<"\t"<<(*pair4.second).second<<endl; cout<<"------------------删除测试------------------\n";
while (!mymap1.empty()){
auto it = mymap1.begin();
cout<<(*it).first<<":"<<(*it).second<<" ";
mymap1.erase(it);//根据迭代器删除
}
multimap_test();
return 0;
}

5、set(treeset)

红黑二叉树变体

特点:集合 元素唯一 自动排序(默认从小到大) 不能按照[]方式插入元素

//两数之和
int main() {
int nums[]{2, 7, 11, 15};
int target = 9;
set<int> myset;
for (int i = 0; i < sizeof(nums)/ sizeof(nums[0]); ++i) {
if(myset.count(target-nums[i])==1){//判断是否存在target-nums[i]
cout<<i;
break;
}
else
myset.insert(nums[i]);
}
return 0;
}

包含仿函数、pair、查找等

void print(set<int> set1){
for (set<int>::iterator iter =set1.begin();iter!=set1.end();iter++) {
cout<<*iter<<"\t";
}
}
void print3(set<int,greater<int>> set1){
for (set<int,greater<int>>::iterator iter =set1.begin();iter!=set1.end();iter++) {
cout<<*iter<<"\t";
}
}
class student{
public:
int age;
string name;
student(string _name,int _age){
name = _name;
age = _age;
}
};
//仿函数
class Funstudent{
public:
bool operator()(const student &left,const student &rigth){
if(left.age<rigth.age)//按照年龄从小到达排序
return true;
else
return false;
}
};
void fanghanshu_pair(){
//仿函数
set<student,Funstudent> myset4;//针对class
student s1("s1",31);//插入s1成功
student s2("s2",14);//插入s2成功
student s3("s3",20);//插入s3成功
student s4("s1",56);//覆盖s1,插入成功
student s5("s5",56);//插入失败
//pair的使用
//pair<iterator,bool> insert( const TYPE& val );
pair<set<student>::iterator,bool> pair1 = myset4.insert(s1);
if(pair1.second)
cout<<"\n插入s1成功"<<endl;
else
cout<<"插入s1失败"<<endl;
pair<set<student>::iterator,bool> pair2 = myset4.insert(s2);
if(pair2.second)
cout<<"插入s2成功"<<endl;
else
cout<<"插入s2失败"<<endl;
pair<set<student>::iterator,bool> pair3 = myset4.insert(s3);
if(pair3.second)
cout<<"插入s3成功"<<endl;
else
cout<<"插入s3失败"<<endl;
pair<set<student>::iterator,bool> pair4 = myset4.insert(s4);
if(pair4.second)
cout<<"插入s4成功"<<endl;
else
cout<<"插入s4失败"<<endl; myset4.insert(s4);
pair<set<student>::iterator,bool> pair5 = myset4.insert(s5);
if(pair5.second)
cout<<"插入s5成功"<<endl;
else
cout<<"插入s5失败"<<endl;
for (set<student,Funstudent>::iterator iter=myset4.begin(); iter !=myset4.end(); ++iter) {
cout<<iter->age<<"\t"<<iter->name<<endl;
}
}
void multiset_test(){
cout<<"---------------multiset--------------"<<endl;
multiset<int> set1;
set1.insert(100);
set1.insert(100);
set1.insert(50);
set1.insert(45);
set1.insert(10);
set1.insert(45);
set1.insert(200);
for (auto x:set1) {
cout<<x<<"\t";
}
}
int main() {
//集合 元素唯一 自动排序(默认从小到大) 不能按照[]方式插入元素
set<int> myset1;//等价set<int,less<int>> myset2;从小到大排序
for (int i = 0; i < 5; ++i) {
int tmp = rand();
myset1.insert(tmp);
}
myset1.insert(100);
myset1.insert(100);//不可插入
myset1.insert(100);//不可插入
print(myset1);
cout<<endl;
cout<<"\n---------------查找测试-------------------\n";
set<int>::iterator it = myset1.find(100);
cout<<"*it:"<<*it<<endl;
myset1.count(100);
cout<<myset1.count(100)<<endl;//结果为1,查找值为100元素的位置
cout<<"lower_bound(100):"<<*myset1.lower_bound(100)<<endl;//结果为100,查找key大于等于100的迭代器
cout<<"upper_bound(100):"<<*myset1.upper_bound(100)<<endl;//结果为6334,查找key大于100的迭代器
//pair<iterator, iterator> equal_range( const key_type& key );
cout<<"equal_range(100):"<<*(myset1.equal_range(100).first)<<"\t"<<*(myset1.equal_range(100).second)<<endl;//结果为100 6334,等价于lower_bound+upper_bound
while (!myset1.empty()){
auto tmp = myset1.begin();
cout<<*tmp<<"\t";
myset1.erase(myset1.begin());//删除首元素
}
cout<<"\n从大到小排序的set:\n";
set<int,greater<int>> myset3;//从大大小排序
for (int i = 0; i < 5; ++i) {
int tmp = rand();
myset3.insert(tmp);
}
myset3.insert(100);
myset3.insert(100);//不可插入
myset3.insert(100);//不可插入
print3(myset3);
cout<<endl;
while (!myset3.empty()){
auto tmp = myset3.begin();
cout<<*tmp<<"\t";
myset3.erase(myset3.begin());//删除首元素
}
fanghanshu_pair();
multiset_test();
return 0;
}

6、deque

要点:双端数组

  1. std::distance()求坐标
  2. std::find()查找元素的迭代器,找不到返回 iter end()
void print(deque<int> dl) {
for (deque<int>::iterator iter = dl.begin(); iter != dl.end(); iter++) {
cout << *iter << "\t";
}
cout << "\nfront:" << dl.front() << " end:" << dl.back() << endl;
} int main() {
deque<int> dl;
dl.push_back(4);
dl.push_back(5);
dl.push_back(6);
dl.push_front(3);
dl.push_front(2);
dl.push_front(1);
print(dl);
dl.pop_back();
dl.pop_front();
print(dl);
auto x = find(dl.begin(),dl.end(),2);
if(x!=dl.end())
cout<<distance(dl.begin(),x)<<endl;//求坐标索引
else
cout<<"Not Found"<<endl;
return 0;
}

7、stack

class studnet{
public:
int age;
void printage(){
cout<<age<<"\t";
}
};
int main() {
stack<int> st;
st.push(1);
st.push(2);
st.push(3);
st.push(4);
while (!st.empty()){
int temp = st.top();
cout<<temp<<"\t";
st.pop();
}
cout<<endl;
stack<studnet> st2;
for (int i = 0; i < 5; ++i) {
studnet temp2;
temp2.age=i+20;
st2.push(temp2);
}
while (!st2.empty()){
studnet temp2 = st2.top();
temp2.printage();
st2.pop();
}
return 0;
}
/*输出
4 3 2 1
24 23 22 21 20
*/

8、queue

class studnet{
public:
int age;
void printage(){
cout<<age<<"\t";
}
};
int main() {
queue<int> queue1;
queue1.push(1);
queue1.push(2);
queue1.push(3);
queue1.push(4);
while (!queue1.empty()){
int temp = queue1.front();
cout<<temp<<"\t";
queue1.pop();
}
cout<<endl;
queue<studnet> queue2;
for (int i = 0; i < 5; ++i) {
studnet temp2;
temp2.age=i+20;
queue2.push(temp2);
}
while (!queue2.empty()){
studnet temp2 = queue2.front();//取队首
temp2.printage();
queue2.pop();
}
return 0;
}
/*
1 2 3 4
20 21 22 23 24
*/

priority_queue包含在同一个头文件 queue中,且方法与queue基本类似,不同之处在于没有了取队首、队尾元素的操作,只能取“优先级最高”的元素,方法蜜汁与stack相似~~,系统默认初始化为最大值队列

int main() {
priority_queue<int> pq1;//默认最大值优先队列
priority_queue<int,vector<int>,less<int>> pq2;//最大值优先队列,less、greater是预定义函数 可以看作是谓词
priority_queue<int,vector<int>,greater<int>> pq3;//最小值优先队列 pq1.push(1);
pq1.push(4);
pq1.push(2);
pq1.push(3);
pq1.push(6);
cout<<"最大值优先队列 ->队首元素:"<<pq1.top();//队首元素是优先级最高的元素,方法与栈类似top
cout<<"\t队列长度:"<<pq1.size()<<endl;
while (pq1.size()>0){
cout<<pq1.top()<<"\t";
pq1.pop();//删除队首元素
}
pq3.push(1);
pq3.push(4);
pq3.push(2);
pq3.push(3);
pq3.push(6);
cout<<endl<<"最小值优先队列->队首元素:"<<pq3.top();
cout<<"\t队列长度:"<<pq3.size()<<endl;
while (pq3.size()>0){
cout<<pq3.top()<<"\t";
pq3.pop();//删除队首元素
}
return 0;
}
/*
最大值优先队列 ->队首元素:6 队列长度:5
6 4 3 2 1
最小值优先队列->队首元素:1 队列长度:5
1 2 3 4 6
*/

9、list(双向链表)

void print(list<int> li) {
for (list<int>::iterator iter = li.begin(); iter != li.end(); iter++) {
cout << *iter << "\t";
}
cout << "\nfront:" << li.front() << " end:" << li.back() << endl;
} class studnet{
public:
int age;
void printage(){
cout<<age<<"\t";
}
};
int main() {
list<int> li;
for (int i = 5; i < 10; ++i) {
li.push_back(i);//尾插法
}
print(li);
for (int i = 4; i >= 1; --i) {
li.push_front(i);//头插法
}
print(li); auto x = find(li.begin(),li.end(),5);
if (x!=li.end())
cout<<"5对应的坐标:"<<distance(li.begin(),x)<<endl;//list的结点index序号从0位置开始
//x=x+1;//出错,list迭代器不支持随机访问,因为内部实现是双向链表
x++;//不报错
x++;//不报错
x++;//不报错
li.insert(x,88);//x=7,则插入后原来7号变8号
print(li);
li.erase(li.begin(),++li.begin());//[,),不删除结尾元素
print(li);
li.push_back(88);
print(li);
li.remove(88);//删除所有为88的结点
print(li);
return 0;
}
/*
5 6 7 8 9
front:5 end:9
1 2 3 4 5 6 7 8 9
front:1 end:9
5对应的坐标:4
1 2 3 4 5 6 7 88 8 9
front:1 end:9
2 3 4 5 6 7 88 8 9
front:2 end:9
2 3 4 5 6 7 88 8 9 88
front:2 end:88
2 3 4 5 6 7 8 9
front:2 end:9
*/

约瑟夫环

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <list>
using namespace std;
int main() {
list<int> persons;
int personnum, number;
scanf("%d%d", &personnum, &number);
for (int i = 0; i < personnum; ++i)
persons.push_back(i + 1);
int target = 0;
for (list<int>::iterator it = persons.begin(); it != persons.end();) {
target++;
if (target == number) {
cout << *it << " ";
it = persons.erase(it);//这步易错
target = 0;
} else it++;
if (it == persons.end())
it = persons.begin();
cout << (persons.begin() == persons.end());
//3 6 9 2 7 1 8 5 10 4
}
return 0;
}

10、string

字符串的输入

(1)用的 string 的 getline

getline(cin,str)函数是处理string类的函数。第二个参数为string类型的变量。读入时第二个参数为string类型,而不是char*,要注意区别

正确写法:

    string str;
while (true) {
getline(cin, str);
if (str == "")
break;
/**下面这种方式也可以
if(str.lenght()==0)
break;
*/
cout << str << endl;
}

注意,下面这种格式的写法,只按回车并不会结束输入,首先getline从标准输入设备上读入字符,然后返回给输入流cin,while判断语句的真实判断对象是cin,也就是判断当前是否存在有效的输入流,这种情况下,不管你怎么输入都跳不出循环,因为你的输入流有效,跳不出循环

错误写法:

while(getline(cin,str))
{
cout<<str<<endl;
}

cin输入后缓冲区的处理

在cin和get的输入中,结束符都没有被写入目标中,但是他们存在差异:

cin与getline()的区别:

​ getline()中的结束符,结束后,结束符不放入缓存区;

​ cin的结束符,结束后,结束符还在缓存区;

在这中情况下,下面实例测试输入1个整数50和一个字符串“test”,字符串str实质接收的是换行符,str被赋值为“”字符串。

错误写法:

    string str;
int num;
cin >> num;
getline(cin, str);
cout << str << endl;

所以在使用 cin 后若要使用 getline() 必须要把前面cin遗留的结束符处理掉,解决方法为:在使用getline()之前,加入一行getline()来处理cin留下的结束符;代码如下:

正确写法:

    string str;
int num;
cin >> num;
getline(cin, str);
getline(cin, str);
cout << str << endl;

字符串中的查找与替换

string.substr(pos,length)从pos截取length个字符,返回字符串

string.replace(pos,length,source),用source替换从pos开始的length的字符

string findReplaceString(string S, vector<int>& indexes, vector<string>& sources, vector<string>& targets) {
if(indexes.empty())
return S;
for (int i = 0;i<indexes.size();i++){
// if(S[indexes[i]]==sources[i][0]){
if(S.substr(indexes[i],sources[i].size())==sources[i]){
S.replace(indexes[i],sources[i].size(),targets[i]);
for(int &x :indexes){
if(x>indexes[i])
x +=(targets[i].size()-sources[i].size());
}
}else
continue;
}
return S;
}

二、Algorithm

1、函数对象(谓词)

入门程序

template <class T>
class FuncShowElem{
public:
int sum = 0;
void operator()(T &t){
cout<<t<<" ";
sum++;
}
void prinfsum(){
cout<<"\n"<<this->sum;
}
};
template <class T>
void FuncShowElem2(T &t){
cout<<t<<" ";
} int main() {
FuncShowElem<int> funcShowElem;//函数对象
vector<int> vector1;
vector1.push_back(1);
vector1.push_back(2);
vector1.push_back(3);
vector1.push_back(4);
cout<<"\n遍历1:";
for_each(vector1.begin(),vector1.end(),FuncShowElem<int>());//匿名函数对象
cout<<"\n遍历2:";
funcShowElem = for_each(vector1.begin(),vector1.end(),funcShowElem);//函数对象,返回函数对象,注意传入的是形参,再返回形参
funcShowElem.prinfsum();
cout<<"\n遍历3:";
for_each(vector1.begin(),vector1.end(),FuncShowElem2<int>);//通过回调函数,谁使用回调函数,谁写回调函数的入口地址
return 0;
}
/*输入
遍历1:1 2 3 4
遍历2:1 2 3 4
4
遍历3:1 2 3 4
*/

一元谓词示例

class isDiv{
public:
int div;
bool operator()(T &t) {
return (t%div==0);
}
isDiv(int _div){
this->div = _div;
}
}; int main() {
vector<int> vector1;
for (int i = 1; i < 10; ++i) {
vector1.push_back(i);
}
isDiv<int> isDiv1(4);
vector<int>::iterator iter ;
iter = find_if(vector1.begin(),vector1.end(),isDiv1);
if (iter!=vector1.end()){
cout<<"vector中第一个被4整除的数"<<*iter<<endl;
} else
cout<<"vector中不存在被四整出的元素"<<endl;
return 0;
}
//输出
//vector中第一个被4整除的数4
//实现字符串转大写
string str1("helloworld");
transform(str1.begin(),str1.end(),str1.begin(),::toupper);
cout<<str1<<endl;
//HELLOWORLD

二元谓词

求和,transform

template <class T>
class SumAdd{
public:
T operator()(T t1,T t2) {
return t1+t2;
}
};
int main() {
vector<int> vector1;
vector<int> vector2;
vector<int> vector3;
for (int i = 1; i < 10; ++i) {
vector1.push_back(i);
}
for (int i = 10; i < 20; ++i) {
vector2.push_back(i);
}
//resize() 函数改变当前vector的大小为size,且对新创建的元素赋值val
vector3.resize(9);
vector<int>::iterator iter;
transform(vector1.begin(),vector1.end(),vector2.begin(),vector3.begin(),SumAdd<int>());
for (iter= vector3.begin(); iter!=vector3.end(); ++iter) {
cout<<*iter<<" ";
}
return 0;
}
/*
11 13 15 17 19 21 23 25 27
*/

排序

bool MyComp(int &a,int &b){
return a>b;
}
void show(int a){
cout<<a<<" ";
}
int main() {
vector<int> vector1;
for (int i = 0; i < 20; ++i) {
vector1.push_back(rand()%100);
}
for (auto x :vector1) {
cout<<x<<" ";
}
cout<<endl;
sort(vector1.begin(),vector1.end(),MyComp);//二元谓词,定义比较元素的函数
for_each(vector1.begin(),vector1.end(),show);//回调函数作谓词,输出vector
return 0;
}
/*输出
41 67 34 0 69 24 78 58 62 64 5 45 81 27 61 91 95 42 27 36
95 91 81 78 69 67 64 62 61 58 45 42 41 36 34 27 27 24 5 0
*/
class compareFun {
public:
bool operator()(const string& string1, const string& string2) {
string temp1;
string temp2;
temp1.resize(string1.size());
temp2.resize(string2.size());
transform(string1.begin(),string1.end(),temp1.begin(),::tolower);
transform(string2.begin(),string2.end(),temp2.begin(),::tolower);
return temp1<temp2;
}
}; int main() {
set<string> set1;
set1.insert("aaaa");
set1.insert("bbbb");
set1.insert("cccc");
set1.insert("dddd");
set1.insert("eeee");
set<string>::iterator iter = set1.find("aAaa");
if (iter != set1.end())
cout << "查找到" << endl;
else
cout << "没有查找到" << endl;
set<string, compareFun> set2;
set2.insert("aaaa");
set2.insert("bbbb");
set2.insert("cccc");
set2.insert("dddd");
set2.insert("eeee");
set<string>::iterator iter2 = set2.find("aAaa");
if (iter2 != set2.end())
cout << "查找到" << endl;
else
cout << "没有查找到" << endl; }
/*
没有查找到
查找到
*/

预定义函数对象

#include <iostream>
#include <algorithm>
#include <set>
#include <functional>
using namespace std; int main() {
plus<int> intAdd;
int x = 10;
int y = 20;
int z = intAdd(x,y);
cout<<z;
plus<string> stringAdd;
string s1 = "aaa";
string s2 = "bbb";
string s3;
s3 = stringAdd(s1,s2);
cout<<"\n"<<s3;
cout<<endl;
vector<string> vector1;
vector1.push_back("bbb");
vector1.push_back("aaa");
vector1.push_back("ddd");
vector1.push_back("ccc");
//从大到小排序
sort(vector1.begin(),vector1.end(),greater<string>());
for_each(vector1.begin(),vector1.end(),[](string x){cout<<x<<" ";});//匿名函数
//计数
vector1.push_back("ccc");
vector1.push_back("ccc");
//函数适配器,equal_to有两个参数,bind2nd将预定义函数和参数绑定
int result = count_if(vector1.begin(),vector1.end(),bind2nd(equal_to<string>(),"ccc"));
cout<<"\n"<<result;
return 0;
}
/*
30
aaabbb
ddd ccc bbb aaa
3
*/

函数适配器

bool greater2(const int &a){
return a>3;
}
class mygreater{
public:
int target = 3;
bool operator()(const int& a){
return a>target;
}
}; /*
* template<typename _Operation, typename _Tp>
inline binder2nd<_Operation>
bind2nd(const _Operation& __fn, const _Tp& __x)
{
typedef typename _Operation::second_argument_type _Arg2_type;
return binder2nd<_Operation>(__fn, _Arg2_type(__x));
}
*/
int main() { vector<int> vector1;
for (int i = 0; i < 10; ++i) {
vector1.push_back(i);
}
for_each(vector1.begin(),vector1.end(),[](int x){cout<<x<<" ";});//匿名函数
int num = count(vector1.begin(),vector1.end(),3);
cout<<endl<<num<<endl;
//通过谓词求大于3 的个数
int result1 = count_if(vector1.begin(),vector1.end(),greater2);//回调函数
int result2 = count_if(vector1.begin(),vector1.end(),mygreater());//自定义函数对象
//通过函数适配器bind2nd指定预定义函数对象的参数,将二元谓词转变为一元谓词
int result3 = count_if(vector1.begin(),vector1.end(),bind2nd(greater<int>(),3));//预定义函数对象 int result4 = count_if(vector1.begin(),vector1.end(),not1(bind2nd(greater<int>(),3)));//预定义函数对象
cout<<"回调函数:"<<result1<<" 自定义函数对象:"<<result2<<" 预定义函数对象:"<<result3<<endl;
cout<<"谓词求小于2 的个数"<<result4<<endl;
return 0;
}
/*
0 1 2 3 4 5 6 7 8 9
1
回调函数:6 自定义函数对象:6 预定义函数对象:6
4
*/

常用算法

for_each()

注意,for_each()是修改性算法,即可以对元素进行修改,返回值是函数对象

/*
* template<typename _InputIterator, typename _Function>
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
__f(*__first);
return _GLIBCXX_MOVE(__f);
}
*/
class showElem{
public:
int num = 0;
void operator()(const int& a){
cout<<a<<" ";
num++;
}
void printNums(){
cout<<num<<endl;
}
};
int main() {
vector<int> vector1;
for (int i = 0; i < 10; ++i) {
vector1.push_back(i);
}
for_each(vector1.begin(),vector1.end(),[](int x){cout<<x<<" ";});//匿名函数
cout<<"\n";
//函数对象做参数、函数对象做返回值
showElem showElem1 = for_each(vector1.begin(),vector1.end(),showElem());//函数对象,只有foreach返回函数对象
cout<<"\n";
showElem1.printNums();
for_each(vector1.begin(),vector1.end(),[](int &x){x++;});//匿名函数,修改元素值
for_each(vector1.begin(),vector1.end(),[](int &x){x++;});//匿名函数,修改元素值
for_each(vector1.begin(),vector1.end(),[](int x){cout<<x<<" ";});//匿名函数
return 0;
}
/*
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
10
2 3 4 5 6 7 8 9 10 11
*/

transform()

与for_each()不同的是,transform的函数对象(回调函数)必须有返回值

int main() {
vector<int> vector1;
for (int i = 0; i < 10; ++i) {
vector1.push_back(i);
}
for_each(vector1.begin(),vector1.end(),[](int x){cout<<x<<" ";});//匿名函数
cout<<"\n";
list<int> mylist;
mylist.resize(vector1.size());
transform(vector1.begin(),vector1.end(),mylist.begin(),bind2nd(multiplies<int>(),10));
//函数对象做参数、函数对象做返回值
for_each(mylist.begin(),mylist.end(),[](int x){cout<<x<<" ";});//匿名函数
return 0;
}
/*
0 1 2 3 4 5 6 7 8 9
0 10 20 30 40 50 60 70 80 90
*/

查找算法

adjacent_find

int main(){
vector<int> vector1;
vector1.push_back(1);
vector1.push_back(2);
vector1.push_back(3);
vector1.push_back(3);
vector1.push_back(4);
vector1.push_back(5);
vector1.push_back(2); vector<int>::iterator iter = adjacent_find(vector1.begin(),vector1.end());
if (iter!=vector1.begin()){
cout<<"值为:"<<*iter<<" "<<"下标位置:"<<distance(vector1.begin(),iter);
} else
cout<<"没有找到相似元素!";
cout<<endl;
auto i2 = std::adjacent_find(vector1.begin(), vector1.end(), std::greater<int>());
if (i2 == vector1.end()) {
std::cout << "The entire vector is sorted in ascending order\n";
} else {
std::cout << "The last element in the non-decreasing subsequence is at: "
<< std::distance(vector1.begin(), i2) << '\n';
}
return 0;
}
/*
值为:3 下标位置:2
The last element in the non-decreasing subsequence is at: 5
*/

find

int main(){
vector<int> vector1;
vector1.push_back(1);
vector1.push_back(2);
vector1.push_back(3);
vector1.push_back(4);
vector1.push_back(5);
vector<int>::iterator iterator1= find(vector1.begin(),vector1.end(),3);
if (iterator1!=vector1.end()){
cout<<"找到了,"<<"下标位置:"<<distance(vector1.begin(),iterator1);
} else
cout<<"没有找到";
return 0;
}
//找到了,下标位置:2

find_if

int main(){
vector<int> vector1;
vector1.push_back(1);
vector1.push_back(2);
vector1.push_back(3);
vector1.push_back(4);
vector1.push_back(5);
vector<int>::iterator iterator1= find_if(vector1.begin(),vector1.end(),[](int x){ return x>3;});
if (iterator1!=vector1.end()){
cout<<"找到了,"<<*iterator1<<" 下标位置:"<<distance(vector1.begin(),iterator1);
} else
cout<<"没有找到";
return 0;
}
//找到了,4下标位置:3

binary_search

int main(){
vector<int> vector1;
vector1.push_back(1);
vector1.push_back(2);
vector1.push_back(3);
vector1.push_back(3);
vector1.push_back(4);
vector1.push_back(5);
vector1.push_back(2);
bool flag = binary_search(vector1.begin(),vector1.end(),4);
if (flag){
cout<<"找到了";
} else
cout<<"没有找到!";
return 0;
}

count

int main(){
vector<int> vector1;
vector1.push_back(1);
vector1.push_back(2);
vector1.push_back(3);
vector1.push_back(3);
vector1.push_back(4);
vector1.push_back(5);
vector1.push_back(2);
int nums= count(vector1.begin(),vector1.end(),3);
if (nums==0){
cout<<"找到了";
} else
cout<<"有找到"<<nums<<"个3";
return 0;
}
/*
有找到2个3
*/

count_if

int main(){
vector<int> vector1;
vector1.push_back(1);
vector1.push_back(2);
vector1.push_back(3);
vector1.push_back(4);
vector1.push_back(5);
int nums= count_if(vector1.begin(),vector1.end(),[](int x){ return x>3;});
if (nums==0){
cout<<"找到了";
} else
cout<<"大于3有"<<nums<<"个";
return 0;
}
//大于3有2个

max_element

max_element() 和 min_element(),这个的话还是蛮好用的,比自己一个循环写下来要快的多了,取容器中的最大最小值

int num[] = { 2, 3, 1, 6, 4, 5 };
cout << "最小值是 " << *min_element(num, num + 6) << endl;
cout << "最大值是 " << *max_element(num, num + 6) << endl;
cout << "最小值是 " << *min_element(num, num + 6, cmp) << endl;
cout << "最大值是 " << *max_element(num, num + 6, cmp) << endl;
/*
最小值是 1
最大值是 6
最小值是 1
最大值是 6
*/

排序算法

merge

int main(){
vector<int> vector1;
vector<int> vector2;
vector<int> vector3;
for (int i = 0; i < 10; ++i) {
vector1.push_back(i);
}
for (int i = 1; i < 10; i+=2) {
vector2.push_back(i);
}
vector3.resize(vector1.size()+vector2.size());
merge(vector1.begin(),vector1.end(),vector2.begin(),vector2.end(),vector3.begin());
for_each(vector3.begin(),vector3.end(),[](int x){cout<<x<<" ";});
return 0;
}
//0 1 1 2 3 3 4 5 5 6 7 7 8 9 9

sort

class student{
public:
string name;
int age;
student(){}
student(string _name,int _age){
age=_age;
name = _name;
}
};
int main(){
vector<student> vector1;
student student1("xiaosun",22);
student student2("laoli",21);
student student3("gaozong",23);
vector1.push_back(student1);
vector1.push_back(student2);
vector1.push_back(student3);
for_each(vector1.begin(),vector1.end(),[](student s){cout<<s.name<<" "<<s.age<<endl;});
sort(vector1.begin(),vector1.end(),[](student a,student b){ return a.age>b.age;});
cout<<"-----------\n";
for_each(vector1.begin(),vector1.end(),[](student s){cout<<s.name<<" "<<s.age<<endl;});
return 0;
}
/*
xiaosun 22
laoli 21
gaozong 23
-----------
gaozong 23
xiaosun 22
laoli 21
*/

rand_shuffle

int main(){
vector<int> vector1;
for (int i = 0; i < 10; ++i) {
vector1.push_back(i);
}
for_each(vector1.begin(),vector1.end(),[](int s){cout<<s<<" ";});
random_shuffle(vector1.begin(),vector1.end());
cout<<"\n-----------\n";
for_each(vector1.begin(),vector1.end(),[](int s){cout<<s<<" ";});
return 0;
}
/*
0 1 2 3 4 5 6 7 8 9
-----------
8 1 9 2 0 5 7 3 4 6*/

reverse

int main(){
vector<int> vector1;
for (int i = 0; i < 10; ++i) {
vector1.push_back(i);
}
for_each(vector1.begin(),vector1.end(),[](int s){cout<<s<<" ";});
reverse(vector1.begin(),vector1.end());
cout<<"\n-----------\n";
for_each(vector1.begin(),vector1.end(),[](int s){cout<<s<<" ";});
return 0;
}
/*
0 1 2 3 4 5 6 7 8 9
-----------
9 8 7 6 5 4 3 2 1 0
*/

拷贝\替换算法

copy

int main(){
vector<int> vector1;
for (int i = 0; i < 10; ++i) {
vector1.push_back(i);
}
vector<int> vector2;
vector2.resize(vector1.size());
copy(vector1.begin(),vector1.end(),vector2.begin());
for_each(vector2.begin(),vector2.end(),[](int s){cout<<s<<" ";});
return 0;
}
//0 1 2 3 4 5 6 7 8 9

replace

int main(){
vector<int> vector1;
for (int i = 0; i < 10; ++i) {
vector1.push_back(i);
} replace(vector1.begin(),vector1.end(),1,11);
for_each(vector1.begin(),vector1.end(),[](int s){cout<<s<<" ";});
return 0;
}

replace_if

int main(){
vector<int> vector1;
for (int i = 0; i < 10; ++i) {
vector1.push_back(i);
} replace_if(vector1.begin(),vector1.end(),[](int x){ return x>5;},11);
for_each(vector1.begin(),vector1.end(),[](int s){cout<<s<<" ";});
return 0;
}
//0 1 2 3 4 5 11 11 11 11

swap

int main(){
vector<int> vector1;
vector<int> vector2;
for (int i = 0; i < 10; ++i) {
vector1.push_back(i);
}
for (int j = 10; j < 20; ++j) {
vector2.push_back(j);
}
for_each(vector1.begin(),vector1.end(),[](int s){cout<<s<<" ";});
for_each(vector2.begin(),vector2.end(),[](int s){cout<<s<<" ";});
swap(vector1,vector2);
cout<<"\n-----------------\n";
for_each(vector1.begin(),vector1.end(),[](int s){cout<<s<<" ";});
for_each(vector2.begin(),vector2.end(),[](int s){cout<<s<<" ";});
return 0;
}
/*
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
-----------------
10 11 12 13 14 15 16 17 18 19 0 1 2 3 4 5 6 7 8 9*/

accumulate

int main(){
vector<int> vector1;
for (int i = 0; i < 10; ++i) {
vector1.push_back(i);
}
for_each(vector1.begin(),vector1.end(),[](int s){cout<<s<<" ";});
int result = accumulate(vector1.begin(),vector1.end(),0);
cout<<endl<<result; return 0;
}
/*
0 1 2 3 4 5 6 7 8 9
45*/

fill

int main(){
vector<int> vector1;
for (int i = 0; i < 10; ++i) {
vector1.push_back(i);
}
for_each(vector1.begin(),vector1.end(),[](int s){cout<<s<<" ";});
fill(vector1.begin(),vector1.end(),1);
cout<<endl;
for_each(vector1.begin(),vector1.end(),[](int s){cout<<s<<" ";});
return 0;
}
/*
0 1 2 3 4 5 6 7 8 9
1 1 1 1 1 1 1 1 1 1*/

集合运算

set_union

int main(){
vector<int> vector1;
for (int i = 0; i < 10; ++i) {
vector1.push_back(i);
}
vector<int> vector2;
for (int i = 3; i < 15; ++i) {
vector1.push_back(i);
}
vector<int> vector3;
vector3.resize(vector1.size()+vector2.size());
set_union(vector1.begin(),vector1.end(),vector2.begin(),vector2.end(),vector3.begin());
for_each(vector3.begin(),vector3.end(),[](int s){cout<<s<<" ";});
return 0;
}
//0 1 2 3 4 5 6 7 8 9 3 4 5 6 7 8 9 10 11 12 13 14

C++_STL基础案例的更多相关文章

  1. 第六节,TensorFlow编程基础案例-保存和恢复模型(中)

    在我们使用TensorFlow的时候,有时候需要训练一个比较复杂的网络,比如后面的AlexNet,ResNet,GoogleNet等等,由于训练这些网络花费的时间比较长,因此我们需要保存模型的参数. ...

  2. SpringBoot2.0 基础案例(12):基于转账案例,演示事务管理操作

    本文源码 GitHub地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 一.事务管理简介 1.事务基本概念 一组业务操作ABCD,要么全部 ...

  3. _00017 Kafka的体系结构介绍以及Kafka入门案例(0基础案例+Java API的使用)

    博文作者:妳那伊抹微笑 itdog8 地址链接 : http://www.itdog8.com(个人链接) 博客地址:http://blog.csdn.net/u012185296 博文标题:_000 ...

  4. Spring Boot 2.x 基础案例:整合Dubbo 2.7.3+Nacos1.1.3(配置中心)

    本文原创首发于公众号:Java技术干货 1.概述 本文将Nacos作为配置中心,实现配置外部化,动态更新.这样做的优点:不需要重启应用,便可以动态更新应用里的配置信息.在如今流行的微服务应用下,将应用 ...

  5. 【7】了解Bootstrap栅格系统基础案例(2)

    ps.这一次要说的是“Responsive column resets”,但是不知道为什么中文官网没有给出翻译,但是在看到案例的时候,感觉这就像一个bug,我自己姑且叫这个是一个高度bug吧,方便自己 ...

  6. 第七节,TensorFlow编程基础案例-TensorBoard以及常用函数、共享变量、图操作(下)

    这一节主要来介绍TesorFlow的可视化工具TensorBoard,以及TensorFlow基础类型定义.函数操作,后面又介绍到了共享变量和图操作. 一 TesnorBoard可视化操作 Tenso ...

  7. 第五节,TensorFlow编程基础案例-session使用(上)

    在第一节中我们已经介绍了一些TensorFlow的编程技巧;第一节,TensorFlow基本用法,但是内容过于偏少,对于TensorFlow的讲解并不多,这一节对之前的内容进行补充,并更加深入了解讲解 ...

  8. SpringBoot2.0 基础案例(14):基于Yml配置方式,实现文件上传逻辑

    本文源码 GitHub地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 一.文件上传 文件上传是项目开发中一个很常用的功能,常见的如头像上 ...

  9. SpringBoot2.0基础案例(01):环境搭建和RestFul风格接口

    一.SpringBoot 框架的特点 1.SpringBoot2.0 特点 1)SpringBoot继承了Spring优秀的基因,上手难度小 2)简化配置,提供各种默认配置来简化项目配置 3)内嵌式容 ...

随机推荐

  1. 2019最好用的自动化测试工具Top 10,果断收藏!

    经常有人在公众号留言或是后台问我,做自动化测试用哪个工具好,或是学哪门编程语言好呢? 这个时候总是无奈的说: 你应该学习Python 或是Java. 你应该掌握Selenium. 又或者你需要学会jm ...

  2. Git,SVN的优缺点及适合的范围,开源项目?公司项目?

    Git,SVN的优缺点及适合的范围,开源项目?公司项目? 使用git不久,粗浅理解: 1)适用对象不同.Git适用于参与开源项目的开发者.他们由于水平高,更在乎的是效率而不是易用性.Svn则不同,它适 ...

  3. java操作mongodb数据库实现新建数据库,新建集合,新建文档

    *首先明确一点,要通过java代码创建mongodb数据库实例,需要同时创建集合和文档. 代码实现: /* 建立与mongodb数据库的连接,可指定参数,如:MongoClient client = ...

  4. asyncio模块

    asyncio模块   这是官网也非常推荐的一个实现高并发的一个模块,python也是在python 3.4中引入了协程的概念. asyncio 是干什么的? 异步网络操作 并发 协程 python3 ...

  5. 洛谷 P1954 [NOI2010]航空管制

    https://www.luogu.org/problemnew/show/P1954 拓扑排序, 注意到如果正着建图("a出现早于b"=>"a向b连边" ...

  6. 转 SecureCRT中文乱码解决方法

    1. 打开对话窗口,在工具栏中点开“选项”,选择“会话选项”.  2. 在打开的“会话选项”中,选择“外观”.  3. 在显示的“窗口和文本外观”中找到“字符编码”.  4. 把“字符编码”设置为“U ...

  7. ZOJ Course Selection System DP

    http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=5565 Course Selection System Time ...

  8. js AES对称加密 16进制和base64格式

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  9. 设置Eclipse可以Debug模式调试JDK源码,并显示局部变量的值

    最近突然萌发了研究JDK源码的想法,所以就想到了在自己常用的Eclipse上可以调试JDK源码. 整个设置过程也很简单: 首先你要安装好JDK(我的JDK安装路径根目录是D:\Java\jdk-8u9 ...

  10. 一张图告诉你,只会NodeJS还远远不够!

    NodeJS看似小巧简单,却威力无边,一张图,秒懂!!! 可能很多人还不会安装,但至少已经会了javascript,或者至少会了jquery,那么js还可以干更多的事情!js还可以干更多的事情!js还 ...