浅谈C++之STL

一、sort

  • sort使用方便,效率较高,底层实现是用快排的方式进行排序

  • 要使用该算法,需要#include 头文件(算法头文件)

  • sort底层实现用的是快速排序

1. sort 用法一

  • 对基本类型的数组从小到大排序:

  • sort(数组名+n1,数组名+n2);

  • n1和n2都是int类型的表达式,可以包含变量

  • 如果n1=0,则 + n1可以不写

  • 将数组中下标范围为[n1,n2)的元素从小到大排序。下标为n2的元素不在排序 区间内

程序样例:对无序数组进行递增排序

using namespace std;
int main(){int a[10]={12,23,423,2,1,53,65,10,32,45};sort(a, a+10);for(int i=0; i<10; i++){cout << a[i] << " ";}return 0;
}
结果:1 2 10 12 23 32 45 53 65 423

2. sort 用法二

  • 对元素类型为T的基本类型数组从大到小排序:

  • sort(数组名+n1,数组名+n2,greater());

  • **greater()**是从大到小排序规则,<>中的T是数据类型,例如int,float,double等等

    泛型概念:

    ①.泛型:就是不使用具体数据类型,而是使用一种通用类型 T 来进行程序设计;T 只是一个占位符,实际在 T 的位置真实的数据类型取决于用户的需求;占位符的替换由编译器在编译阶段完成。

    ②.泛型编程:为了避免因数据类型的不同,而被迫重复编写大量相同业务逻辑的代码,因此发展了泛型及泛型编程技术;泛型编程就是独立于任何特定类型的方式编写代码,常用到STL容器、迭代器、和算法都是泛型编程的例子。

程序样例:对数组进行从大到小排序

#include<bits/stdc++.h>
using namespace std;
int main(){int a[10]={12,23,423,2,1,53,65,10,32,45};sort(a, a+10,greater<int>());for(int i=0; i<10; i++){cout << a[i] << " ";}return 0;
}
结果:423 65 53 45 32 23 12 10 2 1

3. sort 用法三

  • 用自定义的排序规则,对任何类型T的数组排序

  • sort(数组名+n1,数组名+n2,排序规则结构名());

  • 排序规则结构的定义方式:

struct 结构名{bool operator()(const T & a1, const T & a2){//若a1应该在a2前面,则返回true, 否则返回false}
};

程序样例:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct Student { char name[20]; //姓名int id; //学号double gpa;//绩点
};
Student students [] = { {"Jack",112,3.4},{"Mary",102,3.8},{"Mary",117,3.9}, {"Ala",333,3.5},{"Zero",101,4.0}};
struct StudentRule1 { //按姓名从小到大排 bool operator() (const Student & s1,const Student & s2) { if( stricmp(s1.name,s2.name) < 0)return true; return false; }
};
struct StudentRule2 { //按id从小到大排 bool operator() (const Student & s1,const Student & s2) { return s1.id < s2.id; }
};
struct StudentRule3 {//按gpa从高到低排 bool operator() (const Student & s1,const Student & s2) { return s1.gpa > s2.gpa; }
};
void PrintStudents(Student s[],int size){ for(int i = 0;i < size;++i) cout << "(" << s[i].name << "," << s[i].id <<"," << s[i].gpa <<")";       cout << endl;
}
int main() { int n = sizeof(students) / sizeof(Student);      sort(students,students+n,StudentRule1()); //按姓名从小到大排    PrintStudents(students,n); sort(students,students+n,StudentRule2()); //按id从小到大排 PrintStudents(students,n); sort(students,students+n,StudentRule3()); //按gpa从高到低排 PrintStudents(students,n); return 0;
结果:(Ala,333,3.5) (Jack,112,3.4) (Mary,102,3.8) (Mary,117,3.9) (Zero,101,4)    (Zero,101,4) (Mary,102,3.8) (Jack,112,3.4) (Mary,117,3.9) (Ala,333,3.5) (Zero,101,4) (Mary,117,3.9) (Mary,102,3.8) (Ala,333,3.5) (Jack,112,3.4)
}

4. sort 例题:奖学金

题目描述:

某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金。期末,每个学生都有3门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学 排在前面,这样,每个学生的排序是唯一确定的。

任务:先根据输入的3门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前五名名学生的学号和总分。注意,在前5名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。例如,在某个正确答案中,如果前两行的输出数据(每行输出两个数:学号、总分) 是:

7 279
5 279

这两行数据的含义是:总分最高的两个同学的学号依次是77号、55号。这两名同学的总分都是 279279 (总分等于输入的语文、数学、英语三科成绩之和) ,但学号为77的学生语文成绩更高一些。如果你的前两名的输出数据是:

5 279
7 279

则按输出错误处理,不能得分。

输出格式:

共5行,每行是两个用空格隔开的正整数,依次表示前55名学生的学号和总分

输入输出格式:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wg5po9u0-1623129092555)(http://m.qpic.cn/psc?/V13qV41h30gptO/45NBuzDIW489QBoVep5mcdSSPdHLxT03MIsr2i3.xoQSuqn29Rr6KaYMkEoAA7qW28Ih2KLtKKwaXwZjyeeznRfgZoqpp*1YSeZgH9zkaQc!/b&bo=1wMnAgAAAAABF8E!&rf=viewer_4)]

代码实现:

#include<bits/stdc++.h>
using namespace std;
struct Students {int id;   // 学号int c; // 语文成绩int m; // 数学成绩int e; // 英语成绩int sum;
} S[305];
struct cmp {bool operator()(const Students & s1, const Students & s2) {if(s1.sum < s2.sum) { // 总成绩高的排在前面return 0;} else if(s1.sum > s2.sum) {  return 1;} else  { // 总成绩相等,按语文成绩排名if(s1.c > s2.c) {  // 语文成绩相等,学号小的排在前面return 1;} else if(s1.c < s2.c) {return 0;} else {if(s1.id > s2.id)return 0;elsereturn 1;}}}
};
int main() {int n;cin >> n;for(int i=1; i<=n; i++) {S[i].id = i;  // 学号cin >> S[i].c >> S[i].m >> S[i].e;S[i].sum = S[i].c + S[i].m + S[i].e;}sort(S+1, S+1+n, cmp());for(int i=1; i<=5; i++) {cout << S[i].id << " " << S[i].sum << endl;}return 0;
}

二、string类(字符串)

  • 使用string类要包含头文件 #include

  • string对象的初始化:

  • – string s1(“Hello”);

  • – string month = “March”; //常用方法

  • – string s2(8,’x’);//初始化8个x字符

  • 可以将字符赋值给string对象

  • – string s;

  • – s = ‘n’;

程序样例:

#include<bits/stdc++.h>
using namespace std;
int main(){string s1("hello worle");cout << s1 << endl;string s2(8,'x');cout << s2 << endl;string month = "March";cout << month << endl;string s;s = 'n';cout << s << endl;return 0;
}
运行结果:
hello worle
xxxxxxxx
March
n

1. 成员函数 length 用法

  • string 对象的长度用成员函数 length() 读取
#include<bits/stdc++.h>
using namespace std;
int main(){string str = "hello world";cout << str.length();return 0;
}
运行结果:11

2. string 的赋值和连接

  • 单个字符复制

​ s2[5] = s1[3] = ‘a’;

  • 逐个访问 string 对象中的字符

​ string s1(“hello”);

​ for(int i=0; i<s1.length(); i++){

​ cout << s1.at(i) << endl; //可以改成s1[i] 数组的方式使用

​ }

  • 成员函数 at() 会做范围检查,如果超过范围,会抛出 out_of_range 异常,而下标运算符 [] 不会做范围检查。

  • + 运算符连接字符串

    ​ string s1("good "), s2(“morring!”);

    ​ s1 += s2;

    ​ cout << s1; //结果是:good morring!

  • 用成员函数 append() 连接字符串

    ​ string s1("good "), s2(“morring!”);

    ​ s1.append(s2);

    ​ cout << s1; //结果是:good morring!

    ​ s2.append(s1, 3, s1.size()); //s1.size()和s1.length()的功能一样

    ​ cout << s2; //下标为3开始,s1.size()个字符,如果字符串没有足够字符,则复制到字符串最后一个字符

    ​ //结果是:morring!d 。

3. 比较string

  • 用关系运算符比较 string 的大小:== , > , >= , < , <= , != 返回值是bool 类型,成立返回 true,否则返回 false

    例如:

    ​ string s1(“hello”), s2(“hello”), s3(“hell”);

    ​ bool b = (s1 == s2); //结果:1

    ​ b = (s1 == s3); //结果:0

    ​ b = (s1 > s3); //结果:1

  • 用成员函数 compare() 比较 string 的大小

    ​ string s1(“hello”), s2(“hello”), s3(“hell”);

    ​ int f1 = s1.compare(s2); //结果:0 hello == hello

    ​ int f2 = s1.compare(s3); //结果:1 hello > hell

    ​ int f3 = s3.compare(s1); //结果:-1 hell < hello

    ​ int f4 = s1.compare(1,2,s3,0,3); //结果-1 注:前面两个数字表示从下标1到下标2之间的范围 el < hell

    ​ int f5 = s1.compare(0, s1.size(), s3); // 结果:1 hello > hell

4. 子串

  • 成员函数 substr()

    ​ string s1(“hello world”), s2;

    ​ s2 = s1.substr(4, 5); //从下标4开始5个字符

    ​ cout << s2 << endl; //结果:o wor

5. 交换 string

  • 成员函数swap()

    ​ string s1(“hello world”), s2(“really”);

    ​ s1.swap(s2);

    ​ cout << s1 << endl; // 结果:really

    ​ cout << s2 << endl; // 结果:hello world

6. 删除 string 中的字符

  • 成员函数erase()

    ​ string s1(“hello world”);

    ​ s1.erase(5); //删除下标及之后的字符

    ​ cout << s1 << endl; // 结果:hello

    ​ cout << s1.length() << endl; // 结果:5

    ​ cout << s1.size() << endl; //结果:5

7. 在 string 中插入字符

  • 成员函数 insert()

    ​ string s1(“hello world”);

    ​ string s2(“show insert”);

    ​ s1.insert(5, s2); //将s2插入s1下标5的位置

    ​ cout << s1 << endl; //结果:helloshow insert world

    ​ s1.insert(2, s2, 5, 3); //将s2中下标5开始的3个字符插入s1下标2的位置

    ​ cout << s1 << endl; //结果:heinslloshow insert world

8. 转换成 C 语言式 char* 字符串

  • 成员函数 c_str()

    ​ string s1(“hello world”);

    ​ printf("%s\n", s1.c_str()); // 结果:hello world

      //s1.c_str() 返回传统的const char * 类型字符串,且该字符串以 ”\0“ 结尾
    

三、容器概述

可以用于存放各种类型的数据(基本类型的变量,对象等)的数据结构,都是类模板分为三种

  • 顺序容器

    • vector deque list
  • 关联容器
    • set multiset map multimap
  • 容器适配器
    • stack queue priority_queue

1. 顺序容器简介

​ 容器并非排序的,元素的插入位置同元素的值无关。有vector,deque,list 三种。

  • vector 头文件 < vector >

​ 动态数组。元素在内存连续存放,随机存取任何元素都能在常数时间完成。在尾端增删元素具有较佳的性能(大部分情况下是常数时间)

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P6c4LdyV-1623129092557)(http://m.qpic.cn/psc?/V13qV41h30gptO/45NBuzDIW489QBoVep5mcew0MMU0eSu9cfMaefaEz0xxUfYMY4eK7QiRYWPCFWQ.wVf2PSpJjGtJNuf*OrsMDeKGbxUqfPcZH2b3J.81n6I!/b&bo=3wKPAAAAAAABF2I!&rf=viewer_4)]

  • deque 头文件< deque >

    ​ 双向队列,又称循环队列。元素在内存连续存放。随机存取任何元素都能在常数时间完成(但次于vector )。在两端增删元素具有较佳的性能(大部分情况下是常数时间)。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F0hppDtC-1623129092558)(http://m.qpic.cn/psc?/V13qV41h30gptO/45NBuzDIW489QBoVep5mcTETrniJEJk6qSq5aeUuVO5tSro5JxNC5rX1OyGso9YmrEosJ85R3.PfsJY*kpWS9TSxmBzPVI8PU0h2CT6HXTA!/b&bo=iQJjAQAAAAABF9k!&rf=viewer_4)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8r5yn0gB-1623129092559)(http://m.qpic.cn/psc?/V13qV41h30gptO/ruAMsa53pVQWN7FLK88i5nlcCQty89Je2.AvthoGKeDGuEp.pTWX56hbDmvgK.gDY90GX8vNsrSx6eLdmIklI2fl2hdCawiP.U3hIqyqo!/mnull&bo=agKHAQAAAAABB84!&rf=photolist&t=5)]

  • list 头文件< list >

    ​ 双向链表,又称循环连边。元素在内存不连续存放,在任何位置增删元素都能在常数时间完成。不支持随机存取。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZhAigG3f-1623129092560)(http://m.qpic.cn/psc?/V13qV41h30gptO/45NBuzDIW489QBoVep5mceM3f.ytj6DYAVwT5EzlojRHEgcCFvihB9ysQah3GE2aajsiUaJKpnWwEMMtKCjZZoFEXlsy.lCtNaaV5GfwaxU!/b&bo=1wKwAAAAAAABF1U!&rf=viewer_4)]

2. 容器适配器简介

  • stack 头文件< stack>

    ​ 栈,是项的有限序列,并满足序列中别删除、检索和修改的项只能是最近插入序列的项(栈顶的项)。后进后出。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iY3e8muJ-1623129092561)(http://m.qpic.cn/psc?/V13qV41h30gptO/45NBuzDIW489QBoVep5mcSmBFaw6P8B304YTPFWWCu4Qu3jjIKz8dlYat46FDxeQFz7qVPrGraQpOzfWV.7H5qKfPCxm6wm8lvIpAqvgI!/b&bo=YgEXAQAAAAABF0U!&rf=viewer_4)]

  • queue 头文件< queue >

    ​ 队列。插入只可以在尾部进行,删除、检索和修改只允许从头部进行。先进先出。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mr7D8YT5-1623129092561)(http://m.qpic.cn/psc?/V13qV41h30gptO/45NBuzDIW489QBoVep5mcX.HqYrjI5VotswnVkKCON3KbAqiPYyzYXF0ZKyd3VgO9cNFtSUutqEZooahpeM4c*3k5yHUzbfcH6UZKqjHOoU!/b&bo=XQGlAQAAAAABF8g!&rf=viewer_4)]

3. 顺序容器和关联容器中都有的成员函数

  • begin 返回指向容器中第一个元素的迭代器
  • end 返回指向容器中最后一个元素后面的位置的迭代器
  • rbegin 返回指向容器中最后一个元素的迭代器
  • rend 返回指向容器中第一个元素前面的位置的迭代器
  • clear 从容器中删除所有元素
  • erase 从容器中删除一个或几个元素
  • front 返回容器中第一个元素的引用
  • back 返回容器中最后一个元素的引用
  • push_back 在容器末尾添加新元素
  • pop_bakc 删除容器末尾的元素

4. 迭代器

  • 用于指向顺序容器和关联容器中的元素
  • 迭代器用法和指针类似
  • 有const 和非 const 两种
  • 通过迭代器可以读取它指向的元素
  • 通过非const迭代器能 修改器指向的元素

定义一个容类的迭代器的方法:

容器类型::iterator 变量名 或者 容器类名:: const_iterator 变量名

访问一个迭代器指向的元素:

​ *** 迭代器变量名**

迭代器上可以执行 ++ 操作,以使其指向容器中的下一个元素。如果迭代器到达了容器中的最后一个元素的后面,此时在使用它,就会出错,类似与使用 NULL 或

未初始化的指针一样。

迭代器的的方法如何使用,后面结合其他容器一起介绍

(1)双向迭代器

若 p 和 q 都是双向迭代器,则可对 p、q 可进行一下操作:

  • ++p,p++ 使p指向容器中下一个元素
  • –p,p-- 使p指向容器中上一个元素
  • *p 取p指向的元素
  • p = q 赋值
  • p == q,p != q 判断是否相等、不等
(2)随机访问迭代器

若 p 和 q 都是随机访问迭代器,则可对 p、q 进行一下操作:

  • p += i 将 p 向后移动 i 个元素
  • p -= i 将 p 向前移动 i 个元素
  • p + i 指向 p 后面的第 i 个元素的迭代器
  • p - i 指向 p 前面的第 i 个元素的迭代器
  • p[i] p 后面的第 i 个元素的引用
  • p - q p 和 q 之间的元素的个数
  1. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lSbEelMm-1623129092562)(http://m.qpic.cn/psc?/V13qV41h30gptO/45NBuzDIW489QBoVep5mcZ1.En9mR8sx6OGYc10yxu8Sy.YBATywfplDx36.sJ60OK4Ti6SFBCKCtXBWgJNcqmeUKp1N6V2nDFpyJMxBWiI!/b&bo=RQLsAQAAAAABF5o!&rf=viewer_4)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ws1UwhSR-1623129092562)(http://m.qpic.cn/psc?/V13qV41h30gptO/45NBuzDIW489QBoVep5mcTETrniJEJk6qSq5aeUuVO53CIt6drhkJFa*ZZFG8RBSoWjv3W9lYuIrnS.56TqImauCsPZZfMzbvVnxOry5wHg!/b&bo=NQLqAQAAAAABF.w!&rf=viewer_4)]

四、动态数组vector

1. vector数组定义

头文件:#include

定义:vector v;

2. vector 常用的成员函数有

  • 插入元素 v.push_back(n)

  • 检查这个容器是否为空 v.empty()

  • 容器所容纳的元素数 v.size()

  • 清空容器的所有元素 v.clear()

  • 擦除当前元素 v.erase(地址)

  • 移除末尾的元素 v.pop_back()

3.程序代码

#include<bits/stdc++.h>//万能头文件
using namespace std;
int main(){vector<int> v;   //一个存放 int 元素的数组,一开始容器里为空v.push_back(1);  v.push_back(2);  v.push_back(3);  v.push_back(4);  v.push_back(5);  vector<int>::const_iterator it;  //常量迭代器//遍历vector容器中的元素 for(it = v.begin(); it != v.end(); it++){cout << *it << " "; } cout << endl;vector<int>::iterator i;//非常量迭代器for(i = v.begin(); i != v.end(); i++){*i = 100;  //赋值 } for(i = v.begin(); i != v.end(); i++){cout << *i << " ";} cout << endl;v.pop_back();  //删除容器中最后一个元素for(i = v.begin(); i != v.end(); i++){cout << *i << " ";}return 0;
} 运行结果:
1 2 3 4 5
100 100 100 100 100
100 100 100 100

4. vector 实现二维数组

#include<bits/stdc++.h>//万能头文件
using namespace std;
int main(){vector<vector<int> > v(3);// v 有3个元素,每个月元素都是vector<int>容器for(int i=0; i<v.size(); i++){for(int j=0; j<4; j++){v[i].push_back(j);}} // vector二维数组的遍历和一般的二维数组相似 for(int i=0; i<v.size(); i++){for(int j=0; j<4; j++){cout << v[i][j] << " ";}cout << endl;}return 0;
}
运行结果:
0 1 2 3
0 1 2 3
0 1 2 3

5. vector 例题:询问学号

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YQhmmBRb-1623129092563)(http://m.qpic.cn/psc?/V13qV41h30gptO/45NBuzDIW489QBoVep5mceM3f.ytj6DYAVwT5EzlojQuIQSm.OIYPJXz1.TEUUTP.s3QZ.JxGiFk8TqG8pZRGtD*OpwGNdPECtQSQQJS7EM!/b&bo=GQNeAgAAAAABF3Y!&rf=viewer_4)]

代码实现:

#include<bits/stdc++.h>
using namespace std;
vector<int> v;
int main() {int n, m;cin >> n >> m;for(int i=1; i<=n; i++) {int n1;cin >> n1;v.push_back(n1);}auto it = v.begin();for(int j=0;j<m; j++) {int m1;cin >> m1;cout << *(it+m1-1) << endl;}return 0;
}

五、链表 list

1. 链表定义

​ listlst1; //创建空list

    list<int> lst2(5);    //创建含有5个元素的list

2. list 常用的成员函数

  • 在list容器末尾插入或删除元素 l.push_back / l.pop_back()

  • 在list容器头部插入或删除元素 l.push_front / l.pop_front()

  • 判断list容器是否为空 l.empty()

  • 对元素进行排序 l.sort()

  • 返回元素的个数 l.size()

3. 程序代码

#include<bits/stdc++.h>
#include<list>
using namespace std;
int main() {list<int> l;cout << "在list容器末尾插入元素:" ;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);list<int>::iterator it;for(it = l.begin(); it != l.end(); it++) {cout << *it << " ";}cout << endl;cout << "在list容器末尾删除元素:";l.pop_back();l.pop_back();l.pop_back();for(it = l.begin(); it != l.end(); it++) {cout << *it << " ";}cout << endl;cout << "在list容器头部插入元素:";l.push_front(6);l.push_front(7);l.push_front(8);for(it = l.begin(); it != l.end(); it++) {cout << *it << " ";}cout << endl;cout << "在list容器头部删除元素:";l.pop_front();l.pop_front();for(it = l.begin(); it != l.end(); it++) {cout << *it << " ";}cout << endl;cout << "判断list容器是否为空(为空返回1,否则返回为0):";cout << l.empty() << endl; cout << "对元素进行排序:";l.sort();for(it = l.begin(); it != l.end(); it++) {cout << *it << " ";}cout << endl;cout << "返回元素的个数:";cout << l.size() << endl;return 0;
}运行结果:
在list容器末尾插入元素:1 2 3 4 5
在list容器末尾删除元素:1 2
在list容器头部插入元素:8 7 6 1 2
在list容器头部删除元素:6 1 2
判断list容器是否为空(为空返回1,否则返回为0):0
对元素进行排序:1 2 6
返回元素的个数:3

4. list 例题:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vKXChWCX-1623129092563)(http://m.qpic.cn/psc?/V13qV41h30gptO/45NBuzDIW489QBoVep5mcVQh3VkWFHeE5WUCezq*zRJJo6hMtFJ7cSLJdgYPPcmr.OljWjn90hlwzlO36kA26Nru2WOLjSmD1MH0bbxhJrQ!/b&bo=CAKBAwAAAAABF7g!&rf=viewer_4)]

代码实现:

#include<bits/stdc++.h>
using namespace std;
list<int> s;
int main() {int M,N;cin >> M >> N;int count = 0;for(int i = 0; i < N; i++) {int m;cin >> m;auto t = s.begin();int temp = 1;while(t != s.end()) {if(*t == m)temp = 0;t++;}if(temp) {count++;if(s.size() == M) {s.pop_front();s.push_back(m);} elses.push_back(m);}}cout << count << endl;return 0;
}

六、栈 stack

1. 栈的介绍

头文件:#include

定义: stack s;

限定仅在表尾进行插入或删除操作的线性表,表尾—栈顶,表头—栈底,不含元素的空表称空栈。

特点:先进后出(FILO)或后进先出(LIFO)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hhri4S9V-1623129092564)(http://m.qpic.cn/psc?/V13qV41h30gptO/45NBuzDIW489QBoVep5mcZTGs76.T6ZGKlGm8SChHPOiNU*jlV7hG8RmPAqxpsnB2qo3cAaXQlxWMjPXxHmj3vpEyoR2MSFWsaRp1R7x56g!/b&bo=3gIoAQAAAAABF8U!&rf=viewer_4)]

2. 图解stack

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wmANO4ja-1623129092564)(http://m.qpic.cn/psc?/V13qV41h30gptO/45NBuzDIW489QBoVep5mcZ1Oetqsu2a4GPZ06YxLA4KHtQaeJjZ8Dztmus.dKBJtdb7It2p3FldtDpN.inLdu4Tjs*KB0cW9uow95H29M!/b&bo=gQN2AgAAAAABF8Y!&rf=viewer_4)]

3. stack常用成员函数

  • 栈为空返回真 s.empty()
  • 移除栈顶元素 s.pop()
  • 在栈顶增加元素 s.push()
  • 返回栈中元素个数 s.size()
  • 返回栈顶元素 s.top()

4. 程序代码

#include<bits/stdc++.h>
#include<stack>
using namespace std;
int main(){stack<int> s;//在栈顶增加元素s.push(12);s.push(32);s.push(33);s.push(122);cout << "栈顶元素:" << s.top() << endl;//从栈顶弹出两个元素 s.pop();s.pop();cout <<"栈顶元素:" << s.top() << endl;cout << "判断stack容器是否为空(为空返回1,否则返回为0):" << s.empty() << endl;cout << "返回元素的个数:" << s.size() << endl; return 0;
}
运行代码:
栈顶元素:122
栈顶元素:32
判断stack容器是否为空(为空返回1,否则返回为0):0
返回元素的个数:2

5. stack 例题: 括号序列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FrXcubdi-1623129092565)(http://m.qpic.cn/psc?/V13qV41h30gptO/45NBuzDIW489QBoVep5mcZ6K7avGY5bZtDc9nn8aoHphqGo6MJnr5uaETyvhWgt9CnAW33Nqg98DjlSpTKxW1Vy5REIVVStzWSRN.7CH4!/b&bo=BgNyAwAAAAABF0Q!&rf=viewer_4)]

代码实现:

#include<bits/stdc++.h>
using namespace std;
stack<int>q;//定义一个栈
string s,b;//s是输入字符串,b是配对的字符串
int main() {cin>>s;//输入int l=s.size();for (int i=0; i<s.length(); i++) {if (s[i]=='(') {q.push(i); //入栈b[i]=')';//相应的括号匹配上}if (s[i]=='[') {q.push(i); //同理b[i]=']';}if (s[i]==')' || s[i]==']')  //如果是后半边括号if (q.empty() || b[q.top()]!=s[i]) { //这里一定是q.empty不要写错了if (s[i]==')')b[i]='(';elseb[i]='[';//相应的配对} elseb[q.top()]=' ',q.pop();}for (int i=0; i<l; i++) {if (b[i]=='(' or b[i]=='[')cout<<b[i];//输出配对cout<<s[i];//输出原来的字符if (b[i]==')'||b[i]==']')cout<<b[i];}cout<<endl; return 0;
}

七、队列 queue

1. 队列的介绍

头文件:#include

定义:queue q;

队列是一种特殊的线性表; 插入位置只有1个,限制在表尾进行;删除位置也只有1个,限制在表头进行。

特点:先进先出FIFO(First In First Out)

2. 图解队列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WG47Rp8K-1623129092565)(http://m.qpic.cn/psc?/V13qV41h30gptO/45NBuzDIW489QBoVep5mcVZ4hN8rtLRvYSIKvaTW.mIJTxgEJl4GfnKOiVemB6fZOWh7dPVblFLGN.CMziLMbjbym5yJaF1TXLOxWOKGA1c!/b&bo=2gPIAQAAAAABFyA!&rf=viewer_4)]

3. queue常用成员函数

back() 返回最后一个元素
empty 如果队列空则返回真
front() 返回第一个元素
pop() 删除第一个元素
push() 在末尾加入一个元素
size() 返回队列中元素的个数

4. 程序代码

#include<bits/stdc++.h>
#include<queue>
using namespace std;
int main() {queue<int> q;//向空队列添加元素q.push(23);q.push(12);q.push(2);cout << "返回队列中元素的个数:";cout << q.size() << endl;cout << "返回最后一个元素:";cout << q.back() << endl;cout << "返回第一个元素:";cout << q.front() << endl;//删除第一元素q.pop();cout << "返回队列中元素的个数:"; cout << q.size() << endl;cout << "判断stack容器是否为空(为空返回1,否则返回为0):";cout << q.empty() << endl;return 0;}
运行结果:
返回队列中元素的个数:3
返回最后一个元素:2
返回第一个元素:23
返回队列中元素的个数:2
判断stack容器是否为空(为空返回1,否则返回为0):0

5. queue 例题:约瑟夫问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2hq6JWk9-1623129092565)(http://m.qpic.cn/psc?/V13qV41h30gptO/45NBuzDIW489QBoVep5mcdq0HcX.OuoUx1rfokkm3wb2kKGL8yJQle.G*DxW.EHEMp6XmjZD16fwjvskUnWcKp.3PBALgPIY90fsZNv.c!/b&bo=XgRdAwAAAAABFzQ!&rf=viewer_4)]

代码实现:

#include<bits/stdc++.h>
using namespace std;
queue<int> q;
int main() {int n, m;cin >> n >> m;for(int i=1; i<=n; i++) { // 将元素入队q.push(i);}int sum=0;while(!q.empty()) {  // 从头开始,如果不是被点到的人,就把该序号进入队列,然后出队 sum++;           //  否则,就输出并出队 if(sum==m) {cout << q.front() << " ";q.pop();sum=0;}else{q.push(q.front());q.pop();}}return 0;
}

八、优先队列 priority_queue (不常用)

1. 优先队列的介绍

头文件:#include

定义:priority_queue p;

优先队列是队列的一种延伸,优先队列时一种比较重要的数据结构,它是有二项队列编写而成的,可以以O(log n) 的效率查找一个队列中的最大值或者最小值,其中是最大值还是最小值是根据创建的优先队列的性质来决定的。

2. 优先输出大数据

priority_queue<Type, Container, Functional>Type为数据类型, Container为保存数据的容器,Functional为元素比较方式。如果不写后两个参数,那么容器默认用的是vector,比较方式默认用operator<,也就是优先队列是大顶堆,队头元素最大。

示例:

#include<iostream>
#include<queue>
using namespace std;int main(){priority_queue<int> p;p.push(1);p.push(2);p.push(8);p.push(5);p.push(43);for(int i=0;i<5;i++){cout<<p.top()<<endl;p.pop();}return 0;
}
运行结果:
43
8
5
2
1

3. 优先输出小数据

(1)方法一

priority_queue<int, vector, greater > p;

示例:


#include<iostream>
#include<queue>
using namespace std;int main(){priority_queue<int, vector<int>, greater<int> >p;p.push(1);p.push(2);p.push(8);p.push(5);p.push(43);for(int i=0;i<5;i++){cout<<p.top()<<endl;p.pop();}return 0;
}
运行结果:
1
2
5
8
43

(2)方法二:自定义优先级,重载默认的 < 符号 (重载先不用理解)

示例:

#include<iostream>
#include<queue>
#include<cstdlib>
using namespace std;
struct Node{int x,y;Node(int a=0, int b=0):x(a), y(b) {}
};struct cmp{bool operator()(Node a, Node b){if(a.x == b.x)   return a.y>b.y;return a.x>b.x;}
};int main(){priority_queue<Node, vector<Node>, cmp>p;for(int i=0; i<10; ++i)p.push(Node(rand(), rand()));//随机生成整数while(!p.empty()){cout<<p.top().x<<' '<<p.top().y<<endl;p.pop();}return 0;
}
运行结果:
491 9961
5436 4827
11942 2995
15724 19169
16827 23281
18467 41
24464 26962
26500 6334
28145 5705
29358 11478

九、集合 set

1. 集合的介绍

头文件:#include

定义:set s;

在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。set中元素的值不能直接被改变。set内部采用的是一种非常高效的平衡检索二叉树:红黑树,也称为RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树。

特点:

  • set中的元素都是排序好的
  • set中的元素都是唯一的,没有重复的

2. set 常用成员函数

begin() 返回指向第一个元素的迭代器
clear() 清除所有元素
count() 返回某个值元素的个数
empty() 如果集合为空,返回true
end() 返回指向最后一个元素的迭代器
erase() 删除集合中的元素
find() 返回一个指向被查找到元素的迭代器
insert() 在集合中插入元素
lower_bound() 返回指向大于(或等于)某值的第一个元素的迭代器
max_size() 返回集合能容纳的元素的最大限值
rbegin() 返回指向集合中最后一个元素的反向迭代器
rend() 返回指向集合中第一个元素的反向迭代器
size() 集合中元素的数目
swap() 交换两个集合变量
upper_bound() 返回大于某个值元素的迭代器
value_comp() 返回一个用于比较元素间的值的函数

3. 程序代码

#include<bits/stdc++.h>
#include<set>
using namespace std;
int main()
{set<int> s;s.insert(1);s.insert(2);s.insert(3);s.insert(1);s.insert(9);s.insert(7);cout<<"set 的 size 值为 :"<<s.size()<<endl;cout<<"set 的 maxsize的值为 :"<<s.max_size()<<endl;cout<<"set 中的第一个元素是 :"<<*s.begin()<<endl;cout<<"set 中的最后一个元素是:"<<*s.end()<<endl;//end()就是sizeset<int>::iterator it;for(it=s.begin ();it!=s.end ();it++){cout << *it << " ";}cout << endl;s.clear();if(s.empty()){cout<<"set 为空 !!!"<<endl;}cout<<"set 的 size 值为 :"<<s.size()<<endl;cout<<"set 的 maxsize的值为 :"<<s.max_size()<<endl;return 0;
}
运行结果:
set 的 size 值为 :5
set 的 maxsize的值为 :461168601842738790
set 中的第一个元素是 :1
set 中的最后一个元素是:5
1 2 3 7 9
set 为空 !!!
set 的 size 值为 :0
set 的 maxsize的值为 :461168601842738790

十、map

1. map 介绍

Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的。map是一类关联式容器。它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响。对于迭代器来说,可以修改实值,而不能修改key。

2. map 的功能

自动建立Key - value的对应。key 和 value可以是任意你需要的类型。

根据key值快速查找记录,查找的复杂度基本是Log(N),如果有1000个记录,最多查找10次,1,000,000个记录,最多查找20次。

快速插入Key -Value 记录。

快速删除记录

根据Key 修改value记录。

遍历所有记录。

3. map 的使用

头文件:#include

定义:map<T1, T2> m T1表示关键字的数据类型, T2表示值的数据类型

4. map常用成员函数

begin() 返回指向map头部的迭代器

clear() 删除所有元素

count() 返回指定元素出现的次数

empty() 如果map为空则返回true

end() 返回指向map末尾的迭代器

equal_range() 返回特殊条目的迭代器对

erase() 删除一个元素

find() 查找一个元素

insert() 插入元素

lower_bound() 返回键值>=给定元素的第一个位置

max_size() 返回可以容纳的最大元素个数

rbegin() 返回一个指向map尾部的逆向迭代器

rend() 返回一个指向map头部的逆向迭代器

size() 返回map中元素的个数

swap() 交换两个map

upper_bound() 返回键值>给定元素的第一个位置

5. 数据的插入

(1)用insert函数插入pair数据

#include <map>
#include <string>
#include <iostream>
using namespace std;
int main(){map<int, string> mapStudent;mapStudent.insert(pair<int, string>(1, "student_one"));mapStudent.insert(pair<int, string>(2, "student_two"));mapStudent.insert(pair<int, string>(3, "student_three"));map<int, string>::iterator iter;for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)cout<<iter->first<<' '<<iter->second<<endl;return 0;
}
运行结果:
1 student_one
2 student_two
3 student_three

(2)用insert函数插入value_type数据

#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()  {  map<int, string> mapStudent;  mapStudent.insert(map<int, string>::value_type (1, "student_one"));  mapStudent.insert(map<int, string>::value_type (2, "student_two"));  mapStudent.insert(map<int, string>::value_type (3, "student_three"));  map<int, string>::iterator iter;  for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  cout<<iter->first<<' '<<iter->second<<endl;  return 0;
}
运行结果:
1 student_one
2 student_two
3 student_three

(3)用数组方式插入数据(常用)

#include <map>
#include <string>
#include <iostream>
using namespace std;
int main() {map<int, string> mapStudent;mapStudent[1] = "student_one";mapStudent[2] = "student_two";mapStudent[3] = "student_three";map<int, string>::iterator iter;for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)cout<<iter->first<<' '<<iter->second<<endl;return 0;
}
运行结果:
1 student_one
2 student_two
3 student_three

以上三种用法,虽然都可以实现数据的插入,但是它们是有区别的,当然了第一种和第二种在效果上是完成一样的,用insert函数插入数据,在数据的 插入上涉及到集合的唯一性这个概念,即当map中有这个关键字时,insert操作是插入数据不了的,但是用数组方式就不同了,它可以覆盖以前该关键字对 应的值,用程序说明。

mapStudent.insert(map<int, string>::value_type (1, "student_one"));mapStudent.insert(map<int, string>::value_type (1, "student_two"));

上面这两条语句执行后,map中1这个关键字对应的值是“student_one”,第二条语句并没有生效,那么这就涉及到我们怎么知道insert语句是否插入成功的问题了,可以用pair来获得是否插入成功,程序如下

pair<map<int, string>::iterator, bool> Insert_Pair;insert_Pair = mapStudent.insert(map<int, string>::value_type (1, "student_one"));

通过pair的第二个变量来知道是否插入成功,它的第一个变量返回的是一个map的迭代器,如果插入成功的话Insert_Pair.second应该是true的,否则为false。

(4)验证插入函数的作用效果

#include <map>
#include <string>
#include <iostream>
using namespace std;
int main() {map<int, string> mapStudent;pair<map<int, string>::iterator, bool> Insert_Pair;Insert_Pair = mapStudent.insert(pair<int, string>(1, "student_one"));if(Insert_Pair.second == true)cout<<"Insert Successfully"<<endl;elsecout<<"Insert Failure"<<endl;Insert_Pair = mapStudent.insert(pair<int, string>(1, "student_two"));if(Insert_Pair.second == true)cout<<"Insert Successfully"<<endl;elsecout<<"Insert Failure"<<endl;map<int, string>::iterator iter;for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)cout<<iter->first<<' '<<iter->second<<endl;return 0;
}
运行结果:
Insert Successfully
Insert Failure
1 student_one

(5)验证数组形式插入数据的效果

#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()  {map<int, string> mapStudent;mapStudent[1] = "student_one";mapStudent[1] = "student_two";mapStudent[2] = "student_three";map<int, string>::iterator iter;for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)cout<<iter->first<<' '<<iter->second<<endl;return 0;
}
运行结果:
1 student_two
2 student_three

6. 数据的遍历

(1)应用前向迭代器,上面举例程序中到处都是了,略过不表

(2)利用反向迭代器

#include <map>
#include <string>
#include <iostream>
using namespace std;
int main() {map<int, string> mapStudent;mapStudent.insert(pair<int, string>(1, "student_one"));mapStudent.insert(pair<int, string>(2, "student_two"));mapStudent.insert(pair<int, string>(3, "student_three"));map<int, string>::reverse_iterator iter;for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++)cout<<iter->first<<"  "<<iter->second<<endl;return 0;
}
运行结果:
3  student_three
2  student_two
1  student_one

(3):用数组方式

#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()  {map<int, string> mapStudent;mapStudent.insert(pair<int, string>(1, "student_one"));mapStudent.insert(pair<int, string>(2, "student_two"));mapStudent.insert(pair<int, string>(3, "student_three"));int nSize = mapStudent.size();  //map中元素的个数
//此处应注意,应该是 for(int nindex = 1; nindex <= nSize; nindex++)
//而不是 for(int nindex = 0; nindex < nSize; nindex++)for(int nindex = 1; nindex <= nSize; nindex++)cout<<mapStudent[nindex]<<endl;return 0;
}
运行结果:
student_one
student_two
student_three

7. 查找并获取map中的元素

在这里我们将体会,map在数据插入时保证有序的好处。

要判定一个数据(关键字)是否在map中出现的方法比较多,这里标题虽然是数据的查找,在这里将穿插着大量的map基本用法。

这里给出三种数据查找方法

第一种:用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了

第二种:用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器。

查找map中是否包含某个关键字条目用find()方法,传入的参数是要查找的key,在这里需要提到的是begin()和end()两个成员,

分别代表map对象中第一个条目和最后一个条目,这两个数据的类型是iterator.

程序代码:

#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()  {  map<int, string> mapStudent;  mapStudent.insert(pair<int, string>(1, "student_one"));  mapStudent.insert(pair<int, string>(2, "student_two"));  mapStudent.insert(pair<int, string>(3, "student_three"));  map<int, string>::iterator iter;  iter = mapStudent.find(1);  if(iter != mapStudent.end())  cout<<"Find, the value is "<<iter->second<<endl;  else  cout<<"Do not Find"<<endl;  return 0;
}
运行结果:
Find, the value is student_one

8. 从map中删除元素

移除某个map中某个条目用erase()

该成员方法的定义如下:

iterator erase(iterator it);//通过一个条目对象删除

iterator erase(iterator first,iterator last)//删除一个范围

size_type erase(const Key&key);//通过关键字删除

clear()就相当于enumMap.erase(enumMap.begin(),enumMap.end());

这里要用到erase函数,它有三个重载了的函数,下面在例子中详细说明它们的用法

#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()  {map<int, string> mapStudent;mapStudent.insert(pair<int, string>(1, "student_one"));mapStudent.insert(pair<int, string>(2, "student_two"));mapStudent.insert(pair<int, string>(3, "student_three"));//如果你要演示输出效果,请选择以下的一种,你看到的效果会比较好//如果要删除1,用迭代器删除map<int, string>::iterator iter;iter = mapStudent.find(1);mapStudent.erase(iter);//如果要删除1,用关键字删除int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0//用迭代器,成片的删除//一下代码把整个map清空mapStudent.erase( mapStudent.begin(), mapStudent.end() );//成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合//自个加上遍历代码,打印输出吧return 0;
}

9. map中的sort的用法

map中的元素是自动按Key升序排序,所以不能对map用sort函数;

这里要讲的是一点比较高深的用法了,排序问题,STL中默认是采用小于号来排序的,以上代码在排序上是不存在任何问题的,因为上面的关键字是int 型,它本身支持小于号运算,在一些特殊情况,比如关键字是一个结构体,涉及到排序就会出现问题,因为它没有小于号操作,insert等函数在编译的时候过 不去,下面给出两个方法解决这个问题。

这里只解析第一种方法

(1)小于号重载

#include <iostream>
#include <string>
#include <map>
using namespace std;
typedef struct tagStudentinfo  {int      niD;string   strName;bool operator < (tagStudentinfo const& _A) const  {     //这个函数指定排序策略,按niD排序,如果niD相等的话,按strName排序if(niD < _A.niD)return true;if(niD == _A.niD)return strName.compare(_A.strName) < 0;return false;}} Studentinfo, *PStudentinfo; //学生信息int main()  {int nSize;   //用学生信息映射分数map<Studentinfo, int>mapStudent;map<Studentinfo, int>::iterator iter;Studentinfo studentinfo;studentinfo.niD = 1;studentinfo.strName = "student_one";mapStudent.insert(pair<Studentinfo, int>(studentinfo, 90));studentinfo.niD = 2;studentinfo.strName = "student_two";mapStudent.insert(pair<Studentinfo, int>(studentinfo, 80));for (iter=mapStudent.begin(); iter!=mapStudent.end(); iter++)cout<<iter->first.niD<<' '<<iter->first.strName<<' '<<iter->second<<endl;return 0;
}
运行结果:
1 student_one 90
2 student_two 80
mapStudent.erase(iter);
//如果要删除1,用关键字删除
int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0
//用迭代器,成片的删除
//一下代码把整个map清空
mapStudent.erase( mapStudent.begin(), mapStudent.end() );
//成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合
//自个加上遍历代码,打印输出吧
return 0;

}


### 9. map中的sort的用法map中的元素是自动按Key升序排序,所以不能对map用sort函数;这里要讲的是一点比较高深的用法了,排序问题,STL中默认是采用小于号来排序的,以上代码在排序上是不存在任何问题的,因为上面的关键字是int 型,它本身支持小于号运算,在一些特殊情况,比如关键字是一个结构体,涉及到排序就会出现问题,因为它没有小于号操作,insert等函数在编译的时候过 不去,下面给出两个方法解决这个问题。**这里只解析第一种方法**#### (1)小于号重载

#include
#include
#include
using namespace std;
typedef struct tagStudentinfo {
int niD;
string strName;
bool operator < (tagStudentinfo const& _A) const { //这个函数指定排序策略,按niD排序,如果niD相等的话,按strName排序
if(niD < _A.niD)
return true;
if(niD == _A.niD)
return strName.compare(_A.strName) < 0;
return false;
}

} Studentinfo, *PStudentinfo; //学生信息

int main() {

int nSize;   //用学生信息映射分数
map<Studentinfo, int>mapStudent;
map<Studentinfo, int>::iterator iter;
Studentinfo studentinfo;
studentinfo.niD = 1;
studentinfo.strName = "student_one";
mapStudent.insert(pair<Studentinfo, int>(studentinfo, 90));
studentinfo.niD = 2;
studentinfo.strName = "student_two";
mapStudent.insert(pair<Studentinfo, int>(studentinfo, 80));
for (iter=mapStudent.begin(); iter!=mapStudent.end(); iter++)cout<<iter->first.niD<<' '<<iter->first.strName<<' '<<iter->second<<endl;return 0;

}
运行结果:
1 student_one 90
2 student_two 80

_______________________________________________________________________

浅谈C++ 之STL相关推荐

  1. python竞赛_浅谈Python在信息学竞赛中的运用及Python的基本用法

    浅谈Python在信息学竞赛中的运用及Python的基本用法 前言 众所周知,Python是一种非常实用的语言.但是由于其运算时的低效和解释型编译,在信息学竞赛中并不用于完成算法程序.但正如LRJ在& ...

  2. 浅谈C++的智能指针

    一转:http://www.cppblog.com/yearner/archive/2008/11/09/66447.html 浅谈C++的智能指针 内存泄露是C++程序员都头疼的大问题.C++缺乏像 ...

  3. muduo网络库浅谈(一)

    muduo网络库浅谈(一) 序言 第一章 muduo的关键结构 class EventLoop class Channel class Poller 番外 定时任务 class Timestamp c ...

  4. Java开发的B/S程序生成并向客户端发送excel文件:浅谈MIME

    Java开发的B/S程序生成并向客户端发送excel文件:浅谈MIME 1.定义 MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型.是设定 ...

  5. 浅谈对SprutCAM学习认识

    SprutCAM简介 SprutCAM软件在国内被称为司普禄(我猜是音译的),是由俄罗斯开发团队研发,国内昆山司普禄科技公司代理,这个软件十分强大,可以仿真模拟市面上的绝大部分的工业机器人,相对于四大 ...

  6. 春招/秋招面试前必看一文。如何找到 BAT 的实习机会。找实习中的一些困惑,如何解决?。浅谈秋招。

    春招/秋招面试前必看一文 春节过完,不管是大三/研二.还是大四/研三,就要投入到最激烈的春招当中去了,各大公司将会正式招聘,由元旦期间拉开序幕(1 - 2 月),到彻底的进入白热化阶段(3 - 4 月 ...

  7. 浅谈MySQL存储引擎-InnoDBMyISAM

    浅谈MySQL存储引擎-InnoDB&MyISAM 存储引擎在MySQL的逻辑架构中位于第三层,负责MySQL中的数据的存储和提取.MySQL存储引擎有很多,不同的存储引擎保存数据和索引的方式 ...

  8. 【大话设计模式】——浅谈设计模式基础

    初学设计模式给我最大的感受是:人类真是伟大啊!单单是设计模式的基础课程就让我感受到了强烈的生活气息. 个人感觉<大话设计模式>这本书写的真好.让貌似非常晦涩难懂的设计模式变的生活化.趣味化 ...

  9. 学校计算机机房好处,浅谈学校计算机机房维护

    浅谈学校计算机机房维护    现在的学校机房都配置了数量较多的计算机,而且机房的使用非常频繁.对于怎样维护好计算机,特别是计算机软件系统,对广大计算机教师来说是一个很重要且非常现实的问题.下面就本人在 ...

最新文章

  1. python有关迭代器和生成器的面试题_【面试题 | Python中迭代器和生成器的区别?】- 环球网校...
  2. 百练OJ:2713:肿瘤面积
  3. tensorflow中name_scope和variable_scope变量的使用
  4. 压缩vmware中的ubuntu系统(虚拟机瘦身大法)
  5. centos7与centos6区别
  6. 如何把winform图片背景换成透明颜色_如何用photoshop更换图片背景颜色?
  7. 去除UINavigationBar的下边框
  8. 在django中使用vue.js需要注意的地方
  9. vm安装diagram
  10. [NOIP2013D2]
  11. 数字签名的生成和验证
  12. 某天的零点时刻0:0:0 和截至时刻23:59:59
  13. CS5801HDMI转EDP转换器芯片参考资料|CS5801HDMI转EDP转换方案说明
  14. 2022年行研行业研究报告
  15. iPhone6 像素 分辨率
  16. 华语金曲30年30歌
  17. 什么是HTTPS,与HTTP的区别?
  18. 中国铁路 12306 网站的高并发架构带来的思考?研究分析后,果然超牛逼…
  19. 应届毕业生北京租房经验
  20. 洛谷——P3906 Geodetic集合

热门文章

  1. 使用谷歌浏览器控制台提示[DOM] Password field is not contained in a form:
  2. 完全用Linux工作,作者王垠
  3. Python爬虫随笔:爬取iciba上的单词发音文件
  4. 配置路由器接口使用PPP协议封装
  5. The fourth,fifth,sixth,seventh episode of Crazily Speak English
  6. FM知名芯片商芯略总裁因侵权被警方拘留
  7. 大数据技术特点及优势有哪些
  8. USTC科研 7.1 and 7.3 配置环境的学习
  9. LaTeX排版常用字体和格式设置
  10. CSS Grid 网格布局完整教程