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