STL 初步(一)
STL概述
STL: (Standard Template Library) 标准模板库
包含一些常用的算法如排序查找,还有常用的数据结构如可变长数组、链表
、字典等。
使用方便,效率较高
要使用其中的算法,需要#include
4
排序算法 sort
用sort进行排序(用法一)
对基本类型的数组从小到大排序:
sort(数组名+n1,数组名+n2);
n1和n2都是int类型的表达式,可以包含变量
如果n1=0,则 + n1可以不写
将数组中下标范围为[n1,n2)的元素从小到大排序。下标为n2的元素不在排序
区间内
6
用sort进行排序(用法一)
int a[] = {15,4,3,9,7,2,6};
sort(a,a+7); //对整个数组从小到大排序
int a[] = {15,4,3,9,7,2,6};
sort(a,a+3); // 结果:{3,4,15,9,7,2,6}
int a[] = {15,4,3,9,7,2,6};
sort(a+2,a+5); //结果:{15,4,3,7,9,2,6}
7
用sort进行排序(用法二)
对元素类型为T的基本类型数组从大到小排序:
sort(数组名+n1,数组名+n2,greater());
int a[] = {15,4,3,9,7,2,6};
sort(a+1,a+4,greater()); // 结果:{15,9,4,3,7,2,6}
8
用sort进行排序(用法三)
用自定义的排序规则,对任何类型T的数组排序
sort(数组名+n1,数组名+n2,排序规则结构名());
排序规则结构的定义方式:
struct 结构名
{
bool operator()( const T & a1,const T & a2) const {
//若a1应该在a2前面,则返回true。
//否则返回false。
}
}; 9
sort排序规则注意事项
struct 结构名
{
bool operator()( const T & a1,const T & a2) const {
//若a1应该在a2前面,则返回true。
//否则返回false。
}
};
排序规则返回 true,意味着 a1 必须在 a2 前面
返回 false,意味着 a1 并非必须在 a2 前面
排序规则的写法,不能造成比较 a1,a2 返回 true 比较 a2,a1 也返回 true
否则sort会 runtime error
比较 a1,a2 返回 false 比较 a2,a1 也返回 false,则没有问题
10
用sort进行排序(用法三)

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct Rule1 //按从大到小排序
{bool operator()( const int & a1,const int & a2) const {return a1 > a2;
}
};
struct Rule2 //按个位数从小到大排序
{bool operator()( const int & a1,const int & a2) const {return a1%10 < a2%10;
}
};

11
用sort进行排序(用法三)

void Print(int a[],int size) {for(int i = 0;i < size;++i)
cout << a[i] << "," ;
cout << endl;
}
int main()
{int a[] = { 12,45,3,98,21,7};
sort(a,a+sizeof(a)/sizeof(int)); //从小到大
cout << "1) "; Print(a,sizeof(a)/sizeof(int));
sort(a,a+sizeof(a)/sizeof(int),Rule1()); //从大到小
cout << "2) "; Print(a,sizeof(a)/sizeof(int));
sort(a,a+sizeof(a)/sizeof(int),Rule2()); //按个位数从小到大
cout << "3) "; Print(a,sizeof(a)/sizeof(int));
return 0;
}
  1. 3,7,12,21,45,98,
  2. 98,45,21,12,7,3,
  3. 21,12,3,45,7,98,
    用sort对结构数组进行排序(用法三)
#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}};
13
用sort对结构数组进行排序(用法三)
struct StudentRule1 { //按姓名从小到大排
bool operator() (const Student & s1,const Student & s2) const {if( stricmp(s1.name,s2.name) < 0)
return true;
return false;
}
};
struct StudentRule2 { //按id从小到大排
bool operator() (const Student & s1,const Student & s2) const {return s1.id < s2.id;
}
};
struct StudentRule3 {//按gpa从高到低排
bool operator() (const Student & s1,const Student & s2) const {return s1.gpa > s2.gpa;
}
};
14
用sort对结构数组进行排序(用法三)
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;
}
15
用sort对结构数组进行排序(用法三)
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;
}

16
(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)

STL中的二分查找算法
 STL提供在排好序的数组上进行二分查找的算法
binary_search
lower_bound
upper_bound
18
用binary_search进行二分查找(用法一)
在从小到大排好序的基本类型数组上进行二分查找
binary_search(数组名+n1,数组名+n2,值);
n1和n2都是int类型的表达式,可以包含变量
如果n1=0,则 + n1可以不写
查找区间为下标范围为[n1,n2)的元素,下标为n2的元素不在查找区间内
在该区间内查找"等于"值”的元素,返回值为true(找到)或false(没找到)
"等于"的含义: a 等于 B <=> a < b和b < a都不成立
19
用binary_search进行二分查找(用法二)
在用自定义排序规则排好序的、元素为任意的T类型的数组中进行二分查找
binary_search(数组名+n1,数组名+n2,值,排序规则结构名());
n1和n2都是int类型的表达式,可以包含变量
如果n1=0,则 + n1可以不写
查找区间为下标范围为[n1,n2)的元素,下标为n2的元素不在查找区间内
在该区间内查找"等于"值的元素,返回值为true(找到)或false(没找到)
查找时的排序规则,必须和排序时的规则一致!
"等于"的含义: a 等于 b <=> "a必须在b前面"和"b必须在a前面"都不成立20
用binary_search进行二分查找(用法二)

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct Rule //按个位数从小到大排
{bool operator()( const int & a1,const int & a2) const {return a1%10 < a2%10;
}
};
void Print(int a[],int size) {for(int i = 0;i < size;++i) {cout << a[i] << "," ;
}
cout << endl;
}
21
用binary_search进行二分查找(用法二)
int main() {int a[] = { 12,45,3,98,21,7};
sort(a,a+6);
Print(a,6);
cout <<"result:"<< binary_search(a,a+6,12) << endl;
cout <<"result:"<< binary_search(a,a+6,77) << endl;
sort(a,a+6,Rule()); //按个位数从小到大排
Print(a,6);
cout <<"result:"<< binary_search(a,a+6,7) << endl;
cout <<"result:"<< binary_search(a,a+6,8,Rule()) << endl;
return 0;
}

22
3,7,12,21,45,98,
result:1
result:0
21,12,3,45,7,98,
result:0
result:1
"等于"的含义: a 等于 b <=> "a必须在b前面"和"b必须在
a前面"都不成立
用binary_search进行二分查找(用法二)

#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}};
23
用binary_search进行二分查找(用法二)
24
struct StudentRule1 { //按姓名从小到大排
bool operator() (const Student & s1,const Student & s2) const {if( stricmp(s1.name,s2.name) < 0)
return true;
return false;
}
};
struct StudentRule2 { //按id从小到大排
bool operator() (const Student & s1,const Student & s2) const {return s1.id < s2.id;
}
};
struct StudentRule3 {//按gpa从高到低排
bool operator() (const Student & s1,const Student & s2) const {return s1.gpa > s2.gpa;
}
};
用binary_search进行二分查找(用法二)
int main(){Student s;
strcpy(s.name,"Mary");
s.id= 117;
s.gpa = 0;
int n = sizeof(students) / sizeof(Student);
sort(students,students+n,StudentRule1()); //按姓名从小到大排
cout << binary_search( students , students+n,s,
StudentRule1()) << endl;
strcpy(s.name,"Bob");
cout << binary_search( students , students+n,s,
StudentRule1()) << endl;
sort(students,students+n,StudentRule2()); //按id从小到大排
cout << binary_search( students , students+n,s,
StudentRule2()) << endl;
return 0;
}

25
1
0
1
用lower_bound二分查找下界(用法一)
在对元素类型为T的从小到大排好序的基本类型的数组中进行查找
T * lower_bound(数组名+n1,数组名+n2,值);
返回一个指针 T * p;
*p 是查找区间里下标最小的,大于等于"值" 的元素。如果找不到,p指向下标为n2的
元素
26
用lower_bound二分查找下界(用法二)
在元素为任意的T类型、按照自定义排序规则排好序的数组中进行查找
T * lower_bound(数组名+n1,数组名+n2,值,排序规则结构名());
返回一个指针 T * p;
*p 是查找区间里下标最小的,按自定义排序规则,可以排在"值"后面的元素。如果找
不到,p指向下标为n2的元素
27
用upper_bound二分查找上界(用法一)
在元素类型为T的从小到大排好序的基本类型的数组中进行查找
T * upper_bound(数组名+n1,数组名+n2,值);
返回一个指针 T * p;
*p 是查找区间里下标最小的,大于"值"的元素。如果找不到,p指向下标为n2的元素
28
用upper_bound二分查找上界(用法二)
在元素为任意的T类型、按照自定义排序规则排好序的数组中进行查找
T * upper_bound(数组名+n1,数组名+n2,值,排序规则结构名());
返回一个指针 T * p;
*p 是查找区间里下标最小的,按自定义排序规则,必须排在"值"后面的元素。如果找
不到,p指向下标为n2的元素
29
lower_bound,upper_bound用法示例

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct Rule
{bool operator()( const int & a1,const int & a2) const {return a1%10 < a2%10;
}
};
void Print(int a[],int size) {for(int i = 0;i < size;++i) {cout << a[i] << "," ;
}
cout << endl;
} 30
lower_bound,upper_bound用法示例
#define NUM 7
int main()
{int a[NUM] = { 12,5,3,5,98,21,7};
sort(a,a+NUM);
Print(a,NUM); // => 3,5,5,7,12,21,98,
int * p = lower_bound(a,a+NUM,5);
cout << *p << "," << p-a << endl; //=> 5,1
p = upper_bound(a,a+NUM,5);
cout << *p << endl; //=>7
cout << * upper_bound(a,a+NUM,13) << endl; //=>21
31
lower_bound,upper_bound用法示例
sort(a,a+NUM,Rule());
Print(a,NUM); //=>21,12,3,5,5,7,98,
cout << * lower_bound(a,a+NUM,16,Rule()) << endl; // => 7
cout << lower_bound(a,a+NUM,25,Rule()) - a<< endl; // => 3
cout << upper_bound(a,a+NUM,18,Rule()) - a << endl; // => 7
if( upper_bound(a,a+NUM,18,Rule()) == a+NUM)
cout << "not found" << endl; //=> not found
cout << * upper_bound(a,a+NUM,5,Rule()) << endl; // =>7
cout << * upper_bound(a,a+NUM,4,Rule()) << endl; // =>5
return 0;
}

32
STL中的
平衡二叉树
STL中的平衡二叉树数据结构
有时需要在大量增加、删除数据的同时,
还要进行大量数据的查找
34
STL中的平衡二叉树数据结构
有时需要在大量增加、删除数据的同时,
还要进行大量数据的查找
希望增加数据、删除数据、查找数据都能在 log(n)复杂度完成
35
STL中的平衡二叉树数据结构
有时需要在大量增加、删除数据的同时,
还要进行大量数据的查找
希望增加数据、删除数据、查找数据都能在 log(n)复杂度完成
排序+二分查找显然不可以,因加入新数据就要重新排序
36
STL中的平衡二叉树数据结构
有时需要在大量增加、删除数据的同时,
还要进行大量数据的查找
希望增加数据、删除数据、查找数据都能在 log(n)复杂度完成
排序+二分查找显然不可以,因加入新数据就要重新排序
可以使用“平衡二叉树”数据结构存放数据,体现在STL中,就是以
下四种“排序容器” :
multiset set multimap map
37
multiset
multiset用法
multiset st;
定义了一个multiset变量st,st里面可以存放T类型的数据,并且能自
动排序。开始st为空
排序规则:表达式 “a < b” 为true,则 a 排在 b 前面
可用 st.insert添加元素,st.find查找元素,st.erase删除元素,复杂度
都是 log(n)
39
multiset 用法

#include <iostream>
#include <cstring>
#include <set> //使用multiset和set需要此头文件
using namespace std;
int main()
{multiset<int> st;
int a[10]={1,14,12,13,7,13,21,19,8,8 };
for(int i = 0;i < 10; ++i)
st.insert(a[i]); //插入的是a [i]的复制品
multiset<int>::iterator i; //迭代器,近似于指针
for(i = st.begin(); i != st.end(); ++i)
cout << * i << ",";
cout << endl;
输出:1,7,8,8,12,13,13,14,19,21,
40
multiset 用法
i = st.find(22); //查找22,返回值是迭代器
if( i == st.end()) //找不到则返回值为 end()
cout << "not found" << endl;
st.insert(22); //插入 22
i = st.find(22);
if( i == st.end())
cout << "not found" << endl;
else
cout << "found:" << *i <<endl;
//找到则返回指向找到的元素的迭代器
输出:
not found
found:22
41
i = st.lower_bound(13);
//返回最靠后的迭代器 it,使得[begin(),it)中的元素
//都在 13 前面 ,复杂度 log(n)
cout << * i << endl;
i = st.upper_bound(8);
//返回最靠前的迭代器 it,使得[it,end())中的元素
//都在 8 后面,复杂度 log(n)
cout << * i << endl;
st.erase(i); //删除迭代器 i 指向的元素,即12
for(i = st.begin(); i != st.end(); ++i)
cout << * i << ",";
return 0;
}

输出:
13
12
1,7,8,8,13,13,14,19,21,22,
42
1,7,8,8,12,13,13,14,19,21,
multiset 上的迭代器
multiset::iterator p;
p是迭代器,相当于指针,可用于指向multiset中的元素。访问multiset中的元素要通
过迭代器。
与指针的不同:
multiset上的迭代器可 ++ ,–, 用 != 和 == 比较,不可比大小,不可加减整数,不
可相减
43
multiset 上的迭代器
multiset st;
st.begin() 返回值类型为 multiset::iterator,
是指向st中的头一个元素的迭代器
st.end() 返回值类型为 multiset::iterator,
是指向st中的最后一个元素后面的迭代器
对迭代器 ++ ,其就指向容器中下一个元素,-- 则令其指向上一个元素
44
自定义排序规则的multiset 用法
#include
#include
#include
using namespace std;
struct Rule1 {
bool operator()( const int & a,const int & b) const {
return (a%10) < (b%10);
}//返回值为true则说明a必须排在b前面
};
int main() {
multiset<int,greater > st; //排序规则为从大到小
int a[10]={1,14,12,13,7,13,21,19,8,8 };
for(int i = 0;i < 10; ++i)
st.insert(a[i]);
multiset<int,greater >::iterator i;
for(i = st.begin(); i != st.end(); ++i)
cout << * i << “,”;
cout << endl; 输出: 45
21,19,14,13,13,12,8,8,7,1,
自定义排序规则的multiset 用法
multiset<int,Rule1 > st2;
//st2的元素排序规则为:个位数小的排前面
for(int i = 0;i < 10; ++i)
st2.insert(a[i]);
multiset<int,Rule1>::iterator p;
for(p = st2.begin(); p != st2.end(); ++p)
cout << * p << “,”;
cout << endl;
p = st2.find(133);
cout << * p << endl;
return 0;
}
输出:
1,21,12,13,13,14,7,8,8,19,
13 46
自定义排序规则的multiset 用法
multiset<int,Rule1 > st2;
//st2的元素排序规则为:个位数小的排前面
for(int i = 0;i < 10; ++i)
st2.insert(a[i]);
multiset<int,Rule1>::iterator p;
for(p = st2.begin(); p != st2.end(); ++p)
cout << * p << “,”;
cout << endl;
p = st2.find(133);
cout << * p << endl;
return 0;
}
输出:
1,21,12,13,13,14,7,8,8,19,
13 47
find(x): 在排序容器中找一个元素y,使得
“x必须排在y前面”和 “y必须排在x前面”
都不成立
自定义排序规则的multiset 用法

#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
struct Student {char name[20];
int id;
int score;
};
Student students [] = { {"Jack",112,78},{"Mary",102,85},
{"Ala",333,92},{"Zero",101,70},{"Cindy",102,78}};
struct Rule {bool operator() (const Student & s1,const Student & s2) const {if( s1.score != s2.score) return s1.score > s2.score;
else return (strcmp(s1.name,s2.name) < 0);
}
}; 48
自定义排序规则的multiset 用法
int main()
{multiset<Student,Rule> st;
for(int i = 0;i < 5;++i)
st.insert(students[i]); //插入的是students[i]的复制品
multiset<Student,Rule>::iterator p;
for(p = st.begin(); p != st.end(); ++p)
cout << p->score <<" "<<p->name<<" "
<< p->id <<endl;
Student s = { "Mary",1000,85};
p = st.find(s);
if( p!= st.end())
cout << p->score <<" "<< p->name<<" "
<< p->id <<endl;
return 0;
} 49

92 Ala 333
85 Mary 102
78 Cindy 102
78 Jack 112
70 Zero 101
85 Mary 102
set
set的用法
set和multiset的区别在于容器里不能有重复元素
a和b重复  “a必须排在b前面” 和“b必须排在a前面”都不成立
set插入元素可能不成功
51
set的用法

#include <iostream>
#include <cstring>
#include <set>
using namespace std;
int main()
{set<int> st;
int a[10] ={ 1,2,3,8,7,7,5,6,8,12 };
for(int i = 0;i < 10; ++i)
st.insert(a[i]);
cout << st.size() << endl; //输出:8
set<int>::iterator i;
for(i = st.begin(); i != st.end(); ++i)
cout << * i << ","; //输出:1,2,3,5,6,7,8,12,
cout << endl;
52
set的用法
pair<set<int>::iterator, bool> result = st.insert(2);
if( ! result.second ) //条件成立说明插入不成功
cout << * result.first <<" already exists."
<< endl;
else
cout << * result.first << " inserted." << endl;
return 0;
}

输出:
2 already exists.
53
pair<set::iterator, bool>

struct {
set::iterator first;
bool second;
};
pair模板的用法
pair<T1,T2>类型等价于:
struct {
T1 first;
T2 second;
};
例如:pair<int, double> a;
等价于:
struct {
int first;
double second;
} a;
a.first = 1;
a.second = 93.93; 54

北京大学C语言学习第8天相关推荐

  1. 北京大学C语言学习第4天

    指针的概念 指针的基本概念 每个变量都被存放在从某个内存地址(以字节为单位)开始的若干个字节 中 "指针",也称作"指针变量",大小为4个字节(或8个字节) ...

  2. 北京大学C语言学习第6天

    结构的概念 现实需求 在现实问题中,常常需要用一组不同类型的数据来描述一个事物.比如一个 学生的学号.姓名和绩点.一个工人的姓名.性别.年龄.工资.电话- 如果编程时要用多个不同类型的变量来描述一 ...

  3. 北京大学C语言学习第三天

    字符串1 所占字节数为 字符数加1 ,结尾有个\0,字符串长度不包括 \0. 字符串3种形式: 1.双引号括起来的 2.存放于数组中的,以/0结尾 3.string对象 字符串常量: 空串(占据一个字 ...

  4. R语言学习手记 (1)

    R语言学习手记 (1) 经管的会计和财管都会学数据统计与分析R语言这门课,加上我也有点兴趣,就提前选了这门课,以下的笔记由老师上课的PPT.<R语言编程艺术>和<R语言数据科学> ...

  5. 当当网 R 语言学习资料统计分析

    当当网 R 语言学习资料统计分析 一.网络数据的抓取 二.数据清洗与保存 (一)工作目录的修改 (二)导入数据并修改列名 1. 交互式编辑器 2. names()函数 3. rename()函数 (三 ...

  6. C++语言学习(十二)——C++语言常见函数调用约定

    C++语言学习(十二)--C++语言常见函数调用约定 一.C++语言函数调用约定简介 C /C++开发中,程序编译没有问题,但链接的时候报告函数不存在,或程序编译和链接都没有错误,但只要调用库中的函数 ...

  7. 微软提出CLIPBERT:通过稀疏采样的视频语言学习

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 论文是学术研究的精华和未来发展的明灯.小白决心每天为大家带来经典或 ...

  8. c语言错误的等式,C语言学习中几个常见典型错误分析.docx

    C语言学习中几个常见典型错误分析 打开文本图片集 摘要:C语言是一门优秀,应用广泛的结构化程序设计语言,是中职计算机.机电和电子技术等专业一门理论和实践相结合的课程,教学实践中,学生常觉得c语言难学, ...

  9. 二级C语言学习宝典下载,二级C语言学习宝典

    二级C语言学习宝典app是一款专注于全国二级计算机等级C语言学习所开发的应用软件,它能够给你带来全新的功能板块,让你轻松掌握超多优质的考试训练,享受到手机端做题刷题的畅快体验,让你轻松备考,而且在该软 ...

最新文章

  1. 划分vlan,制作trunk口。使同一vlan能互相通讯
  2. 学习SAP项目成功实施的十大条件
  3. Silverlight前景One World One Silverlight
  4. nx二次开发c语言,NX二次开发-UFUN API函数编程基础
  5. mysql 中常用的基本操作
  6. chroma负载机恒压工作原理_双轴撕碎机结构有哪些部分组成?双轴撕碎机工作原理...
  7. 在c语言中定义共用型数据类型的关键字是,C语言的关键字共有32个,根据关键字的作用,可分其为数据类型关键...
  8. 经常使用的文件工具类
  9. 大神总结的一套PCB学习方法! 真得很受用!
  10. win7怎么设置显示计算机,教您win7怎么设置分辨率
  11. IDEA This inspection performs unresolved SQL references check
  12. php 科学计数法 运算,php弱语言特性-计算科学计数法
  13. Laravel的ORM模型的find(),findOrFail(),first(),firstOrFail(),get(),list(),toArray()之间的区别是什么?
  14. 基本知识 100118
  15. 2017校招信息每日汇总(更新至8.4)
  16. 汤臣倍健创业25周年,宣布公司未来3年四个战略重点
  17. 利用Gensim训练关于英文维基百科的Word2Vec模型(Training Word2Vec Model on English Wikipedia by Gensim)
  18. css实现提示信息,纯CSS 实现tooltip 内容提示信息效果
  19. 常见卫星图源下载教程
  20. 硬件比软件难,但为什么硬件待遇不如软件?

热门文章

  1. 说一个岛上有100个人,其中有5个红眼睛
  2. LeetCode 848. Shifting Letters
  3. day26_安卓基础之之Android介绍与入门
  4. 数理基础(概率论)------离散型和连续型分布期望方差公式
  5. 计算机网络 --- 计算机和因特网2
  6. igrp和eigrp详解
  7. AT4896 [ABC161C] Replacing Integer
  8. matlab程序二不能用于负数,matlab中负数的二进制码如何求取
  9. 字节跳动面试锦集(二):项目HR高频面试总结
  10. 记一次ARM-鲲鹏服务器读写parquet报错解决过程