C语言标准库
获取时间 time.h
函数名:time
原型:time_t time (time_t* timer):
功能:获取当前的日历时间。从1970年1月1日到现在的秒数
若 timer 为NULL,则返回日历时间;
若timer非NULL则将获取的日历时间存于timer中。
time_t 即long long型
函数名:gmtime:
原型:struct tm* gmtime (const time_t* timer);
功能:将time_t类型的日历时间转换为 tm 结构的UTC(GMT)时间。
函数名:localtime
原型:struct tm* localtime (const time_t* timer);
功能:将time_t类型的日历时间转换为 tm 结构的 Local time(本地时间)。
例如:time_t localtm=time(NULL);
struct tm* time=localtime (&localtm);
printf("%d",time->min);
函数名:ctime
原型:char* ctime (const time_t* timer);
功能:将time_t类型的日历时间转换为适合人们阅读(human-readable)的字符串格式的时间。
函数名:mktime
原型:time_t mktime (const struct tm* timeptr);
功能:将tm结构体类型的时间转换为 time_t类型的时间
函数名:asctime
原型:char* asctime (const struct tm* timeptr);
功能:将tm结构体类型的时间转换为适合人们阅读的字符串格式的时间。
结构体tm中的元素:
字符串 string.h
系统 windows.h
STL(C++)
algorithm算法
#include<algorithm>
sort排序
reverse翻转数组
reverse(a,a+5);//普通数组
reverse(vec.begin(),vec.end());//vector倒转
unique去重
注意:unique去重需要先用sort排序,去重后重复的元素会放在数组尾端并且返回地址,需要用erase函数实现真正删除。
sort(a,a+5);//数组
int *pos = unique(a,a+5);//unique去重返回尾地址pos
erase(pos,a+5);//从尾地址到最后空间进行删除
//-------------------------------------------------
sort(vec.begin(),vec.end());//vector
vector<int>::itreator it = unique(vec.begin(), vec.end());//unique去重返回尾地址it
vec.erase(it, vec.end());//从尾地址到最后空间进行删除
二分查找
函数原型:
1.lower_bound(起始地址, 末尾地址,x):查找第一个大于等于x目标值的位置
2.upper_bound(起始地址, 末尾地址,x):查找第一个大于x目标值的位置
3.binary_search(起始地址, 末尾地址,x):查找x是否存在于数组或vector中,找到返回true,否则返回false
int *pos1=lower_bound(a,a+5,2)-a;//数组
int *pos2=upper_bound(a,a+5,2)-a;
bool flag=binary_search(a,a+5,2);
//-----------------------------------------------------------
int pos1=lower_bound(vec.begin(),vec.end(),2)-vec.begin();//vector
int pos2=upper_bound(vec.begin(),vec.end(),2)-vec.begin();
bool flag=binary_search(vec.begin(),vec.end(),2);
find暴力查找
函数原型:
find(const_iterator first, const_iterator last, const_reference value);
//返回指针/迭代器,未找到则返回last
string字符串
#include<string>
0.声明
string str1="hello ";
string str2("world");
1.str1.at[n]相当于str1[n]
即取str1中下标为n的字符
2.容量接口函数
str1.size();
//返回str1中字符串的长度,不包括\0
str1.length();
//返回str1中字符串的长度,不包括\0
str1.capacity();
//返回数组长度
str1.empty();
//返回str1是否为空,空返回1,非空返回0
str1.clear();
//清空str1
str1.resize(n);
//改变str1的长度大小,以\0填充,n比str1.size()小时没有变化
str1.reserve(n);
//改变数组空间大小,n比str1.size()小时截断
3.String类对象修改接口
str1.replace(point,length,key);
//从str1下标为point的位置删除length个字符并插入字符串key
str1.insert(point,str);
//在str1下标为point字符的前面插入字符串str
str1.insert(point,str,n);
//在str1下标为point字符的前面插入字符串str中前n个字符
str1.insert(point,str,point2,n);
//在str1下标为point字符的前面插入字符串str中下标从point2开始n个字符
str1.insert(point,n,ch);
//在str1下标为point字符的前面插入n个字符ch
str1.assign(str2);
//将str1重新赋值成字符串str2
str1.assign(str2,point,length);
//将str1重新赋值成字符串str2的从point开始length个字符
str1.erase();
//将str1清空
str1.erase(point);
// 将str1从下标为point开始往后都删掉
str1.erase(point,n);
// 将str1从下标为point开始删除n个字符
str1.reverse();
// 将str1字符串倒过来
str1.swap(str2);
// 交换str1和str2的内容
4.String对象字符串运算相关接口
str1.c_str();
// 返回字符串str1所在的地址
str1.data();
// 返回字符串str1所在的地址
str1=to_string(int);
//可将数值化为字符串,不推荐将浮点型转化为字符串
str1.find(str2);或str1.fint(ch);
// 返回str2在str1中第一次出现的下标位置,未找到返回-1
str1.find(str2,point);
或str1.find(ch,point);
// 从str1下标为point的位置开始找str2,返回从头开始的下标,未找到返回-1
str1.find(str2,point,n);
//返回str2前n个字符在str1中下标point开始第一次出现的下标位置,未找到返回-1
str1.rfind(str2);或str1.rfint(ch);
// 返回str2在str1中最后一次出现的下标位置,未找到返回-1
str1.rfind(str2,point);或str1.rfind(ch,point);
// 从str1下标为point的位置往前找str2,返回字符串开始位置的下标,未找到返回-1
str1.rfind(str2,point,n);
//返回str2前n个字符在str1中下标point往前找出现的下标位置,未找到返回-1
size_t find(const std::string& str, size_t pos = 0) const noexcept;
size_t find(const std::string& str, size_t pos, size_t n) const noexcept;
size_t rfind(const std::string& str, size_t pos = npos) const noexcept;
str1.substr(point);
// 返回str1从下标point开始的子串
str1.substr(point,length);
// 返回str1从下标point开始长度为length的子串
std::string substr(size_t pos = 0, size_t len = npos) const;
getline(cin,str1);
std::istream& getline(std::istream& is, std::string& str, char delim);
//is:流指针
//str:要存入的字符数组
//delim:结束符,不填时默认为'\n',可以手动设置其他结束符
// 获取整行存入str1,返回值为流指针,读取到尽头返回EOF假,
vector
#include<vector>
vector<int> vec;
int a;
vec.push_back(a);//在vector的最后位置添加一个数据
vec.pop_back();//去掉vector的最后一个数据
vec.at(a);//返回下标为a的数据,但如果没有这个下标,它会抛出std::out_of_range异常。
vec.begin();//返回vector头的迭代器
vec.end();//返回vector的最后一个单元+1的迭代器
vec.front();//返回vector第一个值
vec.back();//返回数组的最后一个值
vec.max_size();//得到vector最大可以是多大/ 区别与vec.size()
vec.capacity();//当前vector分配的大小
vec.size();//当前使用数据的大小
vec.resize();//改变容器的大小,如果新大小大于当前大小,将会在容器的尾部添加默认值。
vec.reserve();//更改容器容量。这意味着它不会添加或删除元素,只是预先为未来的增长预留空间。
vec.insert(vec.begin()+n,a);//在第n个位置插入a,时间复杂度为O(N)
vec.erase(it);//删除指针指向的数据项,时间复杂度为O(N)
vec.erase(first,last)//删除first到last(不包括last),时间复杂度为O(N)
vec.clear();//清空当前的vector
vec.rbegin();//返回vector反转后的开始迭代器(其实就是原来的end-1)
vec.rend();//返回vector反转构的结束返回(其实就是原来的begin-1)
vec.empty();//判断vector是否为空,为空返回true,否则返回false
vec.swap(vec2);//与另一个vector交换数据
stack堆栈
#include<stack>
stack<int> st;
s.empty();//堆栈为空则返回true,否则返回false
s.pop();//移除栈顶元素
s.push();//在栈顶增加元素
s.size();//返回栈中元素数目
s.top();//返回栈顶元素
queue队列
#include<queue>
queue
queue<int> q;
q.push();//将元素接到队列的末端;
q.pop();//弹出队列的第一个元素,并不会返回元素的值;
q.front();//访问队首元素
q.back();//访问队尾元素
q.size();//访问队中的元素个数
q.empty();//队列为空返回true,否则返回false
priority_queue
priority_queue<int> q;//默认大顶堆
priority_queue <int,vector<int>,greater<int> > q;//升序队列,小顶堆
priority_queue <int,vector<int>,less<int> >q;//降序队列,大顶堆
q.push(x)//将元素x推入优先队列中。
q.pop()//删除优先队列顶部的元素,并返回该元素的值。
q.top()//返回优先队列顶部的元素的引用。
q.empty()//检查优先队列是否为空。
q.size()//返回优先队列中的元素个数。
q.set_priority_queue(comp)//设置优先队列的比较函数,用于确定元素的优先级。
deque双端队列
1.deque介绍
deque是一个double-ended queue,它的具体实现不太清楚,但知道它具有以下两个特点:它支持[]操作符,也就是支持随即存取,并且和vector的效率相差无几,它支持在两端的操作:push_back,push_front,pop_back,pop_front等,并且在两端操作上与list的效率也差不多。
#include<deque>
deque();//创建一个空deque
deque(int nSize);//创建一个deque,元素个数为nSize
deque(int nSize,const T& t);//创建一个deque,元素个数为nSize,且值均为t
deque(const deque &);//复制构造函数
d.begin();//首元素地址
d.end();//尾元素地址
d.push_back();//插入deque末端
d.push_front();//插入deque首端
d.empty();//deque为空返回true,否则返回false
d.resize(n);//将deque的长度改为n,超出的元素将被删除
d.clear();//清空deque
d.assign(a.begin(),a.end());//将a的begin到end中的元素赋值给deque
d.swap(d2);//等同于swap(d,d2); 交换两个队列
d.reverse();//逆置deque
d.merge(d2);//将deque和d2合并并且变成升序(默认升序)
d.merge(d2,greater<int>());//将deque和d2合并并且变成降序
d.insert(d.begin(),d2,begin(),d2.end());//deque头部插入从d2开始到结尾的元素
d.insert(d.begin(),n);//在deque开始位置插入一个n
d.insert(d.begin(),x,n);//在deque开始位置插入x个n
d.erase(d.begin());//将deque第一个元素删除
d.erase(d.begin(),d.end());//将deque从begin()到end()删除
//以下操作需要empty前置查看deque是否为空
d.front();//获取deque头部元素
d.back();//获取deque最后一个元素
//当deque为空时front()和back()不会报错
d.pop_back();//删除最后一个元素
d.pop_front();//删除第一个元素
//当deque为空是调用pop_back()和pop_front()会使程序崩溃
list双向链表
1.list介绍
list就是数据结构中的双向链表(根据sgi stl源代码),因此它的内存空间是不连续的,通过指针来进行数据的访问,这个特点使得它的随即存取变的非常没有效率,因此它没有提供[]操作符的重载。但由于链表的特点,它可以以很好的效率支持任意地方的删除和插入。
#include<list>
list()//声明一个空列表;
list(n)//声明一个有n个元素的列表,每个元素都是由其默认构造函数T()构造出来的
list(n,val)//声明一个由n个元素的列表,每个元素的值都是val得来的
list(first,last)//声明一个列表,其元素的初始值来源于由区间所指定的序列中的元素
list<int> list1(10,0);//创建长度为10,每个元素的值都为0
l.begin();//首元素地址
l.end();//尾元素地址
l.push_back();//插入list末端
l.push_front();//插入list首端
l.empty();//list为空返回true,否则返回false
l.resize(n);//将list的长度改为n,超出的元素将被删除
l.clear();//清空list
l.assign(a.begin(),a.end());//将a的begin到end中的元素赋值给list
l.swap(l2);//等同于swap(l,l2); 交换两个链表
l.reverse();//逆置list
l.merge(l2);//将list和l2合并并且变成升序(默认升序)
l.merge(l2,greater<int>());//将list和l2合并并且变成降序
l.insert(l.begin(),l2,begin(),l2.end());//list头部插入从l2开始到结尾的元素
l.insert(l.begin(),n);//在list开始位置插入一个n
l.insert(l.begin(),x,n);//在list开始位置插入x个n
l.erase(l.begin());//将list第一个元素删除
l.erase(l.begin(),l.end());//将list从begin()到end()删除
//以下操作需要empty前置查看list是否为空
l.front();//获取list头部元素
l.back();//获取list最后一个元素
//当list为空时front()和back()不会报错
l.pop_back();//删除最后一个元素
l.pop_front();//删除第一个元素
//当list为空是调用pop_back()和pop_front()会使程序崩溃
set集合
头文件set主要包括set和multiset两个容器,分别是“有序集合”和“有序多重集合”,即前者的元素不能重复,而后者可以包含若干个相等的元素。
#include<set>
set<int> se;
multiset<int>se3;//元素可重复
set<int>::iterator it;
int x;
se.begin()//返回指向第一个元素的迭代器
se.clear()//清除所有元素
se.count()//返回某个值元素的个数
se.empty()//如果集合为空,返回true
se.end()//返回指向最后一个元素的迭代器
se.equal_range()//返回集合中与给定值相等的上下限的两个迭代器
se.erase(it) //删除迭代器it指向的元素,时间复杂度为 O(logn)
se.erase(x) //删除s中的x,时间复杂度为 O(logn)
se.find()//返回一个指向被查找到元素的迭代器,若不存在,则返回s.end()
se.count(x) //返回s中x的数量
se.get_allocator()//返回集合的分配器
se.insert()//在集合中插入元素,时间复杂度O(logn)
se.lower_bound()//返回指向大于(或等于)某值的第一个元素的迭代器
se.key_comp()//返回一个用于元素间值比较的函数
se.max_size()//返回集合能容纳的元素的最大限值
se.rbegin()//返回指向集合中最后一个元素的反向迭代器
se.rend()//返回指向集合中第一个元素的反向迭代器
se.size()//集合中元素的数目
se.swap(se2)//交换两个集合变量
se.upper_bound()//返回大于某个值元素的迭代器
se.value_comp()//返回一个用于比较元素间的值的函数
//重载降序排列
struct cmp{
bool operator() (const int &a,const int&b){
return a>b;
}
};
//定义方法
set<int,cmp>s;
map映射
map容器是一个键值对key-value的映射,对于迭代器来说,可以修改实值,而不能修改key。
#include<map>
map<int, string> m;
m.insert(pair<int,string>(1,"Jim"));//添加一个<1,Jim>
m[3]="Jerry";//用数组方式插入元素
m.erase(it);//删除元素,时间复杂度O(1)
m.erase(first, last)//删除元素first到last-1,
m.erase(1);//删除元素,时间复杂度O(n)
m.count(1);// map中存在key值‘1’则返回1,否则返回0
auto iter = m.find(1);//查找key值,返回迭代器位置,否则返回m.end()
iter->first // 使用迭代器读取key值
iter->second // 使用迭代器读取value值
m.size();// 返回map元素个数
m.clear()
map的键和值是唯一的,如果需要一个键对应多个值,就只能用multimap。另外,C++11标准新增了unordered_map,以散列代替map内部的红黑树实现,使其可以用来处理只映射而不按key排序的需求,速度比map要快得多。