算法笔记.胡凡 第6章 C++标准模板库(STL)介绍

6.1 vector常见用法详解

6.1.1.vector定义

vector<int> name;

6.1.2.vector容器元素访问

(1) 下标:v[0]

(2)迭代器

vector<int> vi;
vector<int>::iterator it = vi.begin();

for(int i = 0; i < 5; i++) {

    cout<<*(it + i)<<endl;

}

for(vector<int>::iterator it = vi.begin(); it != vi.end(); it++) {
    cout<<*it<<endl;
}

6.1.3.vector常用函数

(1) push_back():增加一个元素

(2) pop_back():删除一个元素

(3) size():获得vector元素的个数

(4)clear():清除vector中所有的元素

(5) insert(it,x):向迭代器it处插入一个元素x

(6)erase():删除单个元素或者删除某个区间内所有元素。

  • erase(it):删除迭代器it处的元素
  • erase(begin,end):删除迭代器[begin,end)之间的所有元素

6.2 set

6.2.1 set的定义

set<int> st;

6.2.2 set容器内元素的访问

set只能通过迭代器访问。

除了vector和string之外的STL容器都不支持*(it+i)的访问方式,因此只能如下方式枚举

for (set<int>::iterator it = st.begin(); it != st.end(); it++) {
    cout<<*it<<endl;
}

6.2.3 set常用函数

(1) insert():将元素插入set容器,时间复杂度O(log N)

(2) find(value):返回set 中对应值为value的迭代器,时间复杂度O(log N)

(3) erase():删除单个元素或者删除某个区间内的所有元素。

  • st.erase(it):it为需要删除元素的迭代器,可以结合find()函数使用
  • st.erase(value):value为需要删除的元素的值
  • st.erase(begin,end):删除迭代器[begin,end)之间的所有元素

(4)size():获得set内元素的个数

(5) clear():用来清除set中的所有元素

6.2.4 set的作用

set最主要的作用是自动去重并且按照升序排序

6.3 string

6.3.1 string的定义

string str = "abcd";

6.3.2 string中内容的访问

(1)通过下标访问

string.c_str():将字符串转换为字符数组

(2)通过迭代器:同vector,支持直接对迭代器进行加减某个数字,如str.begin() + 3

6.3.3 string常用函数

(1) operator +=:可以将两个string直接拼接起来  str3 = str2 + str1

(2) compare operator:两个string类型可以直接使用==、!=等进行大小比较,比较规则字典排序

(3) length()/size():返回string的长度

(4) insert()

  • insert(pos,string):在pos号位置插入字符串string
  • insert(it,it2,it3):it为原字符串的欲插入位置,it2和it3为待插入字符串的首位迭代器。

(5) erase

  • erase(it):删除迭代器it处的元素
  • erase(first, last):删除迭代器[first, last)中的所有元素
  • erase(pos,length):删除从pos起始处开始的length个字符

(6) clear():清空string中的所有数据

(7) substr(pos, len):返回从pos号位开始、长度为len的子串

(8) string::npos:是一个常数,其本身的值为-1,但由于是unsigned_int类型,因此实际上可以认为是unsigned_int类型的最大值.string::npos用以作为find函数失配时的返回值。

#include<iostream>
#include<string>
using namespace std;
int main() {
    if (string::npos == -1) {
        cout << "-1 is true. <<endl;
    }
    if (string::npos == 4294967295) {
        cout << "4294967295 is true. <<endl;
    }
    return 0;
}

//输出结果:
-1 is true.
4294967295 is true.

(9)find()

  • str.find(str2):当str2是str的子串时,返回其在str中第一次出现的位置,如果不是子串,返回string::npos。
  • str.find(str2,pos):从str的pos号位开始匹配str2,返回值与上面相同。

(10)replace()

  • str.replace(pos, len, str2)把str从pos号位开始、长度为len的子串替换为str2.
  • str.replace(it1,it2,str2)把str的迭代器[it1,it2)范围的子串替换为str2。

【PAT A1060】 Are They Equal

If a machine can save only 3 significant digits, the float numbers 12300 and 12358.9 are considered equal since they are both saved as 0.123×105 with simple chopping. Now given the number of significant digits on a machine and two float numbers, you are supposed to tell if they are treated equal in that machine.

Input Specification:

Each input file contains one test case which gives three numbers N, A and B, where N (<100) is the number of significant digits, and A and B are the two float numbers to be compared. Each float number is non-negative, no greater than 10100, and that its total digit number is less than 100.

Output Specification:

For each test case, print in a line YES if the two numbers are treated equal, and then the number in the standard form 0.d[1]...d[N]*10^k (d[1]>0 unless the number is 0); or NO if they are not treated equal, and then the two numbers in their standard form. All the terms must be separated by a space, with no extra space at the end of a line.

Note: Simple chopping is assumed without rounding.

Sample Input 1:

3 12300 12358.9
结尾无空行

Sample Output 1:

YES 0.123*10^5
结尾无空行

Sample Input 2:

3 120 128
结尾无空行

Sample Output 2:

NO 0.120*10^3 0.128*10^3
结尾无空行

6.4 map

6.4.1 map的定义

map<typename1, typename2> mp;

6.4.2 map容器元素的访问

(1)通过下标访问

mp['c'] = 20

(2)通过迭代器访问:和其他容器相同

map可以使用it->first和it->second访问键和值

6.4.3 map常用函数

(1) find(key)返回键为key的映射的迭代器,时间复杂度为O(logN)

(2) erase()

  • erase(it):删除迭代器it处的元素
  • erase(first, last):删除迭代器[first, last)中的所有元素
  • erase(key):删除键为key的元素

(3)size()获得map中映射的对数

(4)  clear():清空map中的所有元素

6.5 queue

6.5.1 queue定义

queue<int> name;

6.5.2 queue容器内元素的访问

front():访问队首元素

back():访问队尾元素

6.5.3 queue常用函数解析

(1)push():入队

(2)front、back

(3)pop():出队

(4)empty():检测queue是否为空

(5)size()返回queue内元素的个数

6.6 priority_queue

在优先级队列中,队首元素一定是当前队列中优先级最高的那一个。

6.6.1 priority_queue的定义

priority_queue<int> name;

6.6.2 priority_queue容器内元素的访问

优先级队列中没有front函数和back函数,只能通过top函数访问队首元素

6.6.3priority_queue常用函数

(1) push():O(log N)

(2)top():O(1)

(3)pop():O(log N)

(4) empty()判断是否为空

(5)size():返回元素个数

6.6.4 priority_queue内元素优先级的设置

(1)基本数据类型的优先级设置

一般来说数字大的优先级更高。下面两种定义是等价的。

priority_queue<int> q;

priority_queue<int,vector<int>,less<int>> q;

vector<int>表示的是承载底层数据结构堆的容器,第三个参数则是对第一个参数的比较类less<int>表示数字大的优先级大,greater<int>表示数字小的优先级大。

(2)结构体的优先级设置

struct fruit {
    string name;
    int price;
}

//希望按照水果的价格的高位优先级高,就需要重载小于号<

struct fruit{
    string name;
    int price ;
    //重载大于号会编译错误
    //如果想要让价格低的水果优先级更高,把<改成>就行。
    //因为优先级队列默认取排好序的序列尾的元素放在队首
    friend bool operator < (fruit f1, fruit f2) {
        return f1.price < f2.price;
    }
};
priority_queue<fruit> q;

第二种写法

struct cmp{
    bool operator() (fruit f1, fruit f2) {
        return f1.price > f2.price;
    }
};
priority_queue<fruit, vector<fruit>,cmp> q;

如果结构体的数据较为庞大,建议使用引用提高效率

struct cmp{
    bool operator() (fruit &f1, fruit &f2) {
        return f1.price > f2.price;
    }
};
priority_queue<fruit, vector<fruit>,cmp> q;

6.7 stack

6.7.1 stack的定义

stack<int> name;

6.7.2 stack容器内元素的访问

只能通过top()来访问栈顶元素

6.7.3 stack常用函数解析

(1)push

(2)top()

(3)pop()

(4)empty()

(5)size()

6.8 pair

6.8.1 pair定义

pair可以看做一个内部有两个元素的结构体,这两个元素的类型是可以指定的。

struct pair {
    typeName1 first;    
    typeName2 second;
};

使用pair,需要添加头文件#include<utility>,也可以用map来代替utility。

pair<typeName1, typeName2> name;//定义方法

pair<string, int> p("haha",5);//初始化定义

make_pair("haha",5);//使用自带的make_pair函数定义

6.8.2 pair中元素的访问

pair中只有两个元素,分别是first和second,只需要按照正常结构体的方式去访问即可。

p.first, p.second

6.8.3 pair常用函数

(1) 比较操作数

比较规则是先以first的大小为标准,只有当first相等时采取判别second的大小

6.8.4 pair的用途

① 用来代替二元结构及其构造函数,可以节省编码时间

② 作为map的键值来进行插入,如下面的例子。

map<string, int> mp;
mp.insert(make_pair("hehe",10));
mp.insert(pair<string, int>("haha",10));

6.9 algorithm头文件下的常用函数

6.9.1 max()、min()、abs()

6.9.2 swap()

swap(x,y)用来交换x和y的值。

6.9.3 reverse()

reverse(it,it2)可以将数组指针在[it,it2)之间的元素或容器的迭代器进行反转。

int a[10] = {10, 11, 12, 13, 14};
reverse(a, a + 4);//对数组a[0]-a[3]反转

string str = "abasdg";
reverse(str.begin()+2, str.end()+6);//对str[2]~str[5]进行反转

6.9.4 next_premutation()

给出一个序列在全排列中的下一个序列

int a[10] = {1, 2, 3};
do {
    printf("%d%d%d\n",a[0],a[1],a[2]);
}while(next_permutation(a, a+3));//当到达全排列最后一个时会返回false

6.9.5 fill()

fill()可以把数组或者容器中的某一段区间赋为相同的值。fill可以赋值为任意值,memset只能0和-1

int a[5];
fill(a,a+5,233);//a[0]~a[4]赋值为233

6.9.6 sort()

sort(首元素地址,尾元素地址的下一个地址,比较函数(选填));

按照自己定义的方式排序,需要重写cmp函数

bool cmp(int a, int b) {//实现降序
    return a > b;//理解为a > b时,把a放在b前面
}
sort(a,a+4,cmp);
bool cmp(node a, node b) {//实现结构体数组排序
    return a.x > b.x;
}

容器的排序

在STL标准容器中,只有vector、string、deque是可以使用sort。因为set和map本身有序,底层使用的是红黑树

vector<int> s;
sort(s.begin(), s.end(), cmp);

string str3;
sort(str3,str3+3,cmp);

6.9.7 lower_bound() 和 upper_bound()

lower_bound()和upper_bound()需要用在一个有序数组或容器中。

lower_bound(first, last, val)寻找在数组或容器的[first, last)范围内第一个值大于等于val的元素的位置。如果是数组返回指针,如果是容器,返回该位置的迭代器。

upper_bound(first, last, val)寻找在数组或容器的[first, last)范围内第一个值大于val的元素的位置。如果是数组返回指针,如果是容器,返回该位置的迭代器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值