一、数学函数
typedef定义[结构体]
定义结构体的方法为:“struct 结构体名称{ 域定义 };”,
注意花括号的后面还有一个分号。
“typedef struct{ 域定义 }类型名;”的方式定义一个新类型名。
这样,就可以像原生数据类型一样使用这个自定义类型
typedef struct Point{
double x,y
}Point;
double dist(Point a,Point b)
{
return hypot(a.x-b.x,a.y-b.y);
}
//hypot函数
//功能是计算一直角三角形的斜边长度。
//hypot函数头文件math.h或cmath
//hypot(a,b)的返回值为double类型
点结构体
#include<iostream>//istream类输入流ostream类输出流
using namespace std;
//点结构体
struct Point
{
int x, y;
/*
Point( int x=0, int y=0){//普通方法
x = x;
y = y;
}*/
Point( int x=0, int y=0):x(x), y(y){ }
//构造方法,与类名结构体名同名,无返回类型,对象初始化自动调用
//列表法, {}表示函数体
};
ostream& operator << (ostream& out,const Point& p){//&引用,减少时间,得加 //const 保护数据作用 ,改动会报错
printf("p:%x\n", &p);
out << "(" << p.x << "," << p.y<< ")" << endl;
return out;
}
int main( )
{
Point p1, p2(3, 2);
printf("p1:%x\n", &p1);
printf("p2:%x\n", &p2);
// cout << "(" << p1.x << "," << p1.y<< ")" << endl;
// cout << "(" << p2.x << "," << p2.y<< ")" << endl;
cout << p1 << p2;
return 0;
}
断言(assert)
语义如下:如果表达式的值为0(假),则输出错误消息并终止程序的执行(一般还会出对话框,说明在什么地方引发了assert);如果表达式为真,则不进行任何操作。因此,断言失败就表明程序存在一个bug
C/C++的宏(assert)就是这样的断言,当表达式为假时,调用库函数abort()终止程序。
变量
(1)变量的作用域:即变量的作用范围(或有效范围)。
分为:局部变量和全局变量
注:若局部变量与全局变量同名,局部变量优先
(2)变量的生存期:变量从被生成到被撤消的这段时间。即变量占用内存的时间。
分为:动态变量和静态变量
递归
递归函数必须满足两个条件:
(1)必须有一个终止准则(递归的边界条件、递归的结束条件);
(2)在每一次调用自己时,必须是(在某种意义上)更接近于解(递推公式或递归方程)
注:为了防止递归调用无终止地进行,必须在函数内有终止递归调用的手段。常用的办法是加条件判断,满足某种条件后就不再作递归调用,然后逐层返回。
二、STL
STL(Standard Template Library),即标准模板库 大致可以分为三大类:
•容器(container)
•算法(algorithm)
•迭代器(iterator)。
泛类型
template <typename T>
T => 泛类型
sample:
T max(T x,T y)
STL容器:
向量(vector) //描 述:连续存储的元素 //实现头文件<vector>
列表(list) //描 述:由节点组成的双向链表,每个节点包含着一个元素//实现头文件<list>
双向队列(deque) //描 述: 连续存储的指向不同元素的指针所组成的数组 //实现头文件<deque>
集合(set) //描 述:由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能拥有相同的次序//实现头文件<set>
多重集合(multiset) //描 述:允许存在两个次序相等的元素的集合 //实现头文件<set>
栈(stack) //描 述:后进先出的值的排列 //实现头文件<stack>
队列(queue) //描 述:先进先出的值的排列 //实现头文件<queue>
优先队列(priority_queue) //描 述:元素的次序是由作用于所存储的值对上的某种谓词决定的的一种队列 //实现头文件<queue>
映射(map) //描 述:由{键,值}对组成的集合,以某种作用于键对上的谓词排列 //实现头文件<map>
多重映射(multimap) //描 述:允许键对有相等的次序的映射//实现头文件 <map>
哈希表(Unordered_map) //描 述:无序映射,用于存储键值和映射值组合成的元素的关联容器,并允许基于其键快速检索各个元素//实现头文件<unordered_map>
vector 动态数组
头文件
#include <vector>
注: vector容器能存放任何类型的对象
定义vector数组
## 定义int型数组
vector <int> a; ## a为空
vector <int> b(a); ## 用a定义b
vector <int> a(100) ; ## a有100个为0的元素
vector <int> a(100, 6); ## a有100个为6的元素
## 定义string型数组
vector <string> a(10," null"); ## 10个值为null的元素
vector <string> vec(10,"hello"); ## 10个值为hello的元素
vector <string> b(a. begin(), a. end()); ## b是a的复制
## 定义结构型数组
struct point { int x, y; };
vector <point> a;
## 定义二维数组
vector <point> a[maxn]; ## 行静态,列动态
访问方式
## 下标访问
cout << a[i] << endl;
## 指针访问,用于以下情况
cout << *a.begin() << endl;
cout << *a.end() << endl;
## 迭代器访问
vector<int>::iterator it;
for(it=vec.begin();it!=vec.end();it++)
cout<<*it<<endl;
## 指针移动访问(最好别用,优先用迭代器,这个方法不知道合不合法,其实和下标访问区别不大)
vector<int> *p = &a;
for(int i = 0;i < a.size();i++)
cout << (*p)[i] << endl;
常规操作
基础函数
a.push_back(); ## 尾部添加元素
a.size(); ## 返回元素个数大小
a.empty(); ## 返回是否为空,bool值
a.resize(); ## 改变数组大小,变小删除后面元素,变大自动补0
a.clear(); ## 清空
————————————————————————————————————————————————————————————————————————————————————————————————————
插入与删除
a.insert(a.begin() + i,k); ## 在下标为i的元素前插入k
a.insert(a.end(),k,m); ## 尾部插入k个m
a.pop_back(); ## 删除尾部元素
a.erase(a.begin() + i); ## 删除下标为i的元素(下标为2)
a.erase(a.begin() + i,a.begin() + j); ## 删除区间[i,j - 1]内的元素
————————————————————————————————————————————————————————————————————————————————————————————————————
翻转与排序
reverse(a.begin() + i,a.begin() + j); ## 翻转区间[i,j - 1]内的元素
sort(a.begin() + i,a.begin() + j); ## 对区间[i,j - 1]内的元素排序
可直接用的比较函数
less(降序)
greater(升序)
————————————————————————————————————————————————————————————————————————————————————————————————————
寻找
vector<int>::iterator result = find(L.begin( ) + i,L.begin( ) + j,m); ## 在区间[i,j - 1]内寻找m
cout << result - a.begin() << endl; ## 输出m值的下标位置
stack 栈
注:规则(先进后出)
头文件
#include <stack>
定义stack
stack <int> a;
常规操作
基础函数
a.push(x); # 将x放到栈顶
a.pop(); # 删除栈顶元素
a.size(); # 返回栈内元素个数
a.empty(); # 返回栈是否为空
queue队列
注:先进先出,公平原则
头文件
#include <queue>
定义queue
queue <Type> q; 定义队列,Type为数据类型,如int,float,char等
访问方式
同理,对于queue而言,中间的元素是无法访问的,只能通过a.front()访问栈顶元素
a.front();
常规操作
基础函数
q. push(item); # 把item放进队列
q.front(); # 返回队首元素,但不会删除
q.pop(); # 删除队首元素
q.back(); # 返回队尾元素
q.size(); # 返回元素个数
q.empty(); # 检查队列是否为空
set 集合
注:去重性,有自动排序的功能
头文件
#include <set>
定义set
set <int> a;
访问方式
迭代器访问
set <int> :: iterator it;
for(it = a.begin();it != a.end();it++){
cout << *it << endl;
}
常规操作
基础函数
a.insert(x); # 插入x元素
a.erase(a.begin()); # 注意此处函数内要填迭代器,a.begin()实质上貌似就是迭代器
a.clear(); # 清空
a.empty();
a.size();
a.find(k); # 返回一个迭代器,指向键值k
a.lower_bound(k); # 返回一个迭代器,指向键值不小于k的第一个元素
a.upper_bound(k); # 返回一个迭代器,指向键值大于k的第一个元素
map 映射
注:映射,去重性,有自动排序的功能
头文件
#include <map>
定义map
map <int,int> a;
赋值
a[x]=c;
常规操作
基础函数
a.insert(x); # 存在这个东西,但写起来贼麻烦,直接用赋值即可
a.erase(a.begin()); # 注意此处函数内要填迭代器,a.begin()实质上貌似就是迭代器
a.clear(); # 清空
a.empty();
a.size();
a.find(k); # 返回一个迭代器,指向键值k 找不到就map::end()
三、常用技巧
sort函数
自己重载()运算符,
struct comp{
bool operator()(const int &a1, const int &a2){
return (a1%10)<(a2%10);
}
};
sort(a,a+x,comp());
————————————————————————————————————————————————————————————————————————————————————————————————————
直接写一个cmp函数
bool comp(const int &odd1,const int &odd2)
{
return odd1>odd2;
}
sort(a,a+x,comp);
总结
时间超限较难解决
路漫漫其修远兮,吾将上下而求索