其他分享
首页 > 其他分享> > acm1_BUPT

acm1_BUPT

作者:互联网

ACM

c++标准库

今天的重点:

<vector>、<string>、<algorithm>

以后还会见到:

<queue>、<stack>、<set>、<map>、<bitset>、<functional>、<complex>

c标准库常用函数回顾

<cstring>

strlen() 字符串长度

strcmp() 字符串比较

strcpy() 字符串拷贝

memset() 暴力清空,按字节清空

memset(str,0,sizeof(str))

memset(str,-1,sizeof(str))

memset(str,0x3f3f3f3f,sizeof(str))

memcpy() 暴力拷贝

<cmath>

三角函数、指数函数、浮点取整函数

<cstdlib>

qsort() C语言快排,复杂,不使用

rand() 随机数

malloc() free() c语言动态分配内存

<ctime>

time(0) 从1970年到现在的秒数(配合随机数)

#include<ctime>

srand(time(0));

int a = clock();

...

int b = clock() - a;

clock() 程序启动到目前位置的毫秒数

<cctype>

isdigit()、isalpha(),判断字符是否为数字、大小写字母

C++ STL<vector>数组

vector可以被看成一个“超级数组”,它既可以和C语言的数组一样可以用下标访问,也可以像链表一样动态改变长度。

vector<int> arr1(100);

int arr2[100];

vector<int> list;

list.push_back(1);

list.push_back(2);

与普通 的数组类似,vector也可以使用指针来访问遍历每个元素。STL中的指针被称为"迭代器(iterator)"

vector<int> arr1(100);

int arr2[100];

vector<int>::iterator p1 = arr1.begin(;

int* p2 = arr2;

arr1[0]=100;

printf("%d",*p1)

char* p;

for(p = str;*p;p++)

{

}

vector<int>::iterator p2;

for(p2=arr1.begin();p2!=arr1.end();p2++)

{

}

vector常见操作

list.size() 数组元素个数O(1)

list.clear() 一键清空数组 O(n)

list.empty() 数组是否为空O(1)

list.begin() 数组的首元素迭代器O(1)

list.end() 数组最后一个元素的下一个元素的迭代器O(1)

list.erase(p1) 删除数组某个迭代器所在位置的数字O(n)

list.push_back(1) 往数组后面添加元素O(1)

list.pop_back() 删除数组最后一个元素O(1)

C++ STL<string> 字符串

字符串string可以看成一个特殊的vector

string和C语言字符串的关系就和vector和普通数组的关系一样

string str1 = "hello";

char str2[] = "world";

string str3;

str3.push_back('!');

cout<<str1<<" "<<str2<<str3<<endl;

vector有的操作string基本都有,唯一区别是size的复杂度

所有参数为字符产地地方既可以是string也可以是C字符串

string str = "hello";

str.length();str.size();//O(n)

str.insert(1,"aaa");//在下标为1处插入一个字符或字符串O(n)

str.insert(str.begin(),'a');//在迭代器处插入一个字符或字符串O(n)

str.c_str();//返回C语言字符串,用于printf() O(n)

str.append(str2);//把str2拼接到str后面O(n)

str.compare(str2);strcmp(str,str2)==0;

str==str2;

str += str2;

str += 'a';

str.push_back('a');//O(1)

C++STL <algorithm>算法函数

#include <algorithm>

algorithm和之前两个头文件不同,它没有定义什么新的类型,而是定义了很多使用的算法,极大简化了代码量

sort快速排序

int arr[] {2,3,1,5,4};

int n = 5;

vector<int> arr1 {2,3,1,5,4};

sort(arr1.begin(),arr1.end());

//排序开始指针,结束指针(最后一个元素的下一个元素的指针)

sort(arr,arr+n);//O(nlogn)

for(int i = 0; i < n; i++)

{
    printf("%d\n",arr[i]);
}

和C语言qsort一样,sort可以使用自定义的比较函数,比较函数参数是两个待比较变量,返回值是比较的bool值,内部排序函数是按小于关系来的,排序结果是升序,如果按大于关系,则得到降序结果,如下

bool cmpInt(int a, int b)

{
    return a > b;

}

vector<int> arr;

arr.push_back(2);

arr.push_back(3);

arr.push_back(1);

arr.push_back(4);

sort(arr.begin(),arr.end(),cmpInt);
struct Point
{
    int x, y;
};
Point points[1111];
bool cmp(Point a, Point b)
{
    if(a.x != b.x)
    {
        return a.x < b.x;
    }
    return a.y < b.y;
}
int main()
{
    sort(points, points + 10, cmp)
}

自己定义的机构体要写比较函数

其他algorithm函数

//最大最小值O(1)
min(1,2);max(1,2);
//数组最大最小指针O(n)
min_element(arr.begin(),arr.end());
max_element(arr.begin(),arr.end());
//把数组中第n小(从0开始算)的数放到第n个位置
//类似快排,并且保证它左边的比它小,右边的比它大(不一定全排好序)
//O(n)
nth_element(arr.begin(),arr.begin()+n,arr.end());
//交换任意两个同类型变量O(1)
swap(arr[0],arr[1]);
//反转数组O(n)
reverse(arr.begin(),arr.end());
//假设arr已经被排好了序
//使arr中不出现重复的数字(去重)
//返回去重后数组的结束指针
//O(n)
int newLength = unique(arr.begin(),arr.end()) - arr.begin();
//unique需要在sort之后使用
//unique大多数情况下是用于离散化的,线段树与树状数组

lower_bound一般被用来二分查找

灵活运用这两个函数可以得到有序数组中第一个比查找值大、小的数据

//查找对应元素是否存在
//O(logn)
bool isExist = binary_search(arr.begin(),arr.end(),1);//true

//两个函数都是在做一件事
//如果把一个数插入有序数组,它应该插入到哪个位置
//lower_bound返回第一个插入位置的指针,upper_bound返回最后一个位置的指针
//O(logn)
int firstLoc = lower_bound(arr.begin(),arr.end(),2)-arr.begin();//1
int lastLoc = upper_bound(arr.begin(),arr.end(),2)-arr.begin();//2

<stack>

STL大部分数据结构和vector一样,都会自带size()和empty()函数

stack操作包括入、出、获取栈顶元素,复杂度均为O(1)

stack<int> stk;
stk.push(1);
int topElement = stk.top();
stk.pop();
stk.empty();
stk.size();

<queue>

<queue>包含queue和priority_queue(优先队列)两种数据结构,二者用法和stack完全相同

//加入和删除O(1)
queue<int> que;
que.push(1);
int frontElement = que.front();
que.pop();
que.empty();
que.size();
//加入和删除logn
priority_queue<int> que2;
que2.push(1);
int minElement = que2.top();
que2.pop();
que2.empty();
que.size();

<set>

<set>包含set(集合)、multiset(多重集)

set用来保存很多很多元素,并能够在O(logn)的时间内查找、删除、添加某个元素

迭代器的++和--能够在O(logn)的时间里找到第一个比它大(小)的数

set自带去重,而multiset允许元素重复,通过count可以获得某个元素的数量

set是用某种平衡树实现的

set<int> st;
st.insert(1);
st.find(1);
st.erase(1);

multiset<int> mst;
mst.insert(1);
mst.insert(1);
mst.count(1);//2

<map>(映射)

map包含的第一个数据结构是pair,它可以由任意两种类型构成

当不想写结构,又要用到两个相关联的变量时,可以用pair

pair自带了比较函数,默认先比第一个元素再比第二个元素

pair<int,int> origin;
origin = make_pair(0,0);
origin.first == origin.second;
origin.swap;//返回swap的新pair

pair<string,int> id;
id = make_pair("somebody",110);

map的第二个数据结构是map(映射)

map可以看成一个超级数组,可以把字符串或者其他类型当做数组的下标

插入、查询、删除操作复杂度都是O(logn)

map内部使用了pair,所有可以通过insert一个pair来插入

pair<string,int> id;
id = make_pair("somebody",110);

map<string,int> studentHeight;
studentHeight["小明"] = 170;
studentHeight["小红"] = 150;
studentHeight.insert(id);
studentHeight.erase("小明");

map<string,int> height =
{
    {"1",1},
    {"2",2},
    {"3",3}
};

<bitset>位集合

bitset是一个由0和1构成的数组,其占用空间较小

bitset不仅可以和数组一样用下标访问,还可以进行位运算

bitset<1000> bst;

bst[0] = 1;bst.set(0);
bst[0] = 0;bst.reset(0);
bst << 1;bst >> 1;bst ^= 1;bst &= 1;
bst.count();//1的个数
bst.to_string();
bst.to_ullong();

<functional>在ACM只是配合priority_queue一起使用

<complex>C++中的复数类,一般用不到,算模长

<unordered_map>、

分别是<set>和<map>另一种实现版本。这两种数据结构不允许按大小顺序遍历元素,但能O(1)地访问和添加一个元素

这两个数据结构是基于哈希的,对于每种对象都要提供一个计算哈希函数的方法。基础类型、标准库类型都自带了哈希函数,不用自己写,用起来和普通的set、map一样。但对自己定义的结构构建unordered_set和unordered_map时要额外提供一个哈希函数,有些题目卡map的时间,用unordered_map就能过

以上头文件都不需要记忆,只要

#include <bits/stdc++.h>

就能一键包含所有头文件(vs除外)

其他

1s时限内能做的运算次数大约为1e8,根据复杂度来算是否会超时

G++在输出double时不能用%lf,要用%f,不然会WA到/(ㄒoㄒ)/~~

注意多组用例时的EOF、初始化。初始化的常数时间也得估计好

数据范围及运算结果均在1e9以内时,可以令const int INF = 0x3f3f3f3f,表示无穷大值。并且可以用memset(arr,INF,sizeof(arr))来令数组初始化为无穷大

标签:arr,数组,int,BUPT,begin,acm1,vector,str
来源: https://www.cnblogs.com/waynew/p/12444854.html