- 有序的集合A,B可用数组、list、vector*//s1,s2->inserter*
1.merge() //将两个有序序列归并为一个有序序列,元素总个数不变
merge(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(s3,s3.begin()))
2.set_union() //求集合A,B的并集
set_union(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(s3,s3.begin()))
3.set_difference()//求集合A,B的差(A-B)
set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(s3,s3.begin()))
4.set_symmetric_difference()//求集合A,B的对称差((A-B)并(B-A))
set_symmetric_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(s3,s3.begin()))
5.set_intersection()//求集合A,B的交集
set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(s3,s3.begin()))
- priority_queue<Type, Container, Functional>其中Type 为数据类型,Container为保存数据的容器,Functional 为元素比较方式。Container必须是用数组实现的容器,如vector等等,但不能用 list。STL里面默认用的是vector。
priority_queue<int,vector<int>,greater<int> >
- 顺序性容器
///int可用string等替换
vector<int>
list<int>
map<int,int>
set<int>
queue<int>
stack<int>
- 迭代器interator常用遍历
for(vector<int>::iterator it=a.begin();it !=a.end();it++)
{
cout<<*it<<endl;
//vector<int>可以换用list<int>等
}
- c++万能头文件
#include<bits/stdc++.h>
- 读入
string s;
getline(cin,s);//遇到回车结束
cin>>s;//遇到空白符结束
#include<string>
#include<sstream>
#include<iostream>
using namespace std;
int main()
{
stringstream ss;
// 将多个字符串放入ss中
ss<<"first"<<"second ";
//输出ss
cout<<ss.str() << endl;
//清空ss(不用类型转换)
ss.str("");
int first,second;
// 插入字符串
ss<<"379";
// 转换为int类型
sstream>>first;
cout<<first<<endl;
// 进行多次类型转换必须先clear()
ss.clear();
// 插入bool值
sstream<<true;
// 转换为int类型
sstream>>second;
cout<<second<<endl;
return 0;
}
- string类型的赋值
char ch;
string s;
string ss;
//将字符ch赋值给字符串s
s+=ch;
//将字符串ss赋值给字符串s
s.assign(a);
//将字符串ss部分赋值给字符串s,start是首位置,len是截取长度
s.substr(start,len);
s.assign(ss,start,len);
//对字符串s赋n个相同的字符ch
s.assing(n,ch)
- make_pair的用法
//make_pair函数的定义如下:
template pair make_pair(T1 a, T2 b)
{
return pair(a, b);
}
//简易理解
//make_pair(7, 'x') 等价于 pair<int, char>(7, 'x')
//make_pair()不用特别指出类型是什么,还可以接受隐式的类型转换灵活度高
- strchr()和strrchr()
char *strchr(const char *s,char c);
char *strrchr(const char *s,char c);
strchr函数表示在字符串 s 中查找字符 c,返回字符 c 第一次在字符串 s 中出现的位置,如果未找到,返回 NULL。strchr 函数在字符串 s 中从左到右查找字符 c,找到字符 c 第一次出现的位置就返回,返回值指向这个位置,如果找不到字符 c 就返回 NULL。
strrchr函数同样表示在字符串 s 中查找字符 c,返回字符 c 第一次在字符串 s 中出现的位置,如果未找到字符 c,则返回 NULL。但strrchr函数在字符串 s 中是从右向左查找字符 c,找到字符 c 第一次出现的位置就返回,返回值指向这个位置。 - fgets()
函数原型:
char fgets (char *str,int size,FILE* stream)*
*str: 字符型指针
size: 复制到str中的字符串的长度,包含NULL
*stream:将要读取的文件流。
注意:每次只读取一行,每次最多只能读取n-1个字,当遇到换行符或者EOF时,即使当前位置在n-1之前也读出结束。 - substr()
basic_string substr(a,b) basic_string substr(a);
返回本字符串的一个子串从a开始,长b个字符。如果没有b,将是从a开始到结束。这样,substr()函数将简单的返回从index开始的剩余的字符串。
string s("What we have here is a failure to communicate");
string sub=s.substr(21);
cout<<"The original string is "<<s<<endl;
cout<<"The substring is "<<sub<<endl;
//显示:
//The original string is What we have here is a failure to communicate
//The substring is a failure to communicate
- map容器的按key排序和按value排序
typedef pair<string, int> PAIR;
map<string, int> namescore;
struct CmpByValue
{
bool operator()(const PAIR& lhs, const PAIR& rhs)
{
return lhs.second < rhs.second;
}
};
struct CmpByKeyLength
{
bool operator()(const string& k1, const string& k2)
{
return k1.length() < k2.length();
}
};
- strncpy函数
char *strncpy(char *s2, const char *s1, size_t n);
函数strncpy从s1指向的数组中最多复制n个字符到s2指向的数组中。如果s1指向的数组是一个比n短的字符串,则在s2定义的数组后面补空字符,直到写入了n个字符。 - s.substr()
s.substr(a,b)//从a开始到b
s.substr(b)//从0开始到b
s.substr()//全部 - find_first_of() 查找在字符串中第1个出现的字符c,而函数find_last_of()查找最后一个出现的c。匹配的位置是返回值。如果没有匹配发生,则返回-1.
- multimap
Multimaps和maps很相似,但是MultiMaps允许重复的元素。 - deque的用法
非变动性操作
c.size(); //元素数量
c.empty(); //判断大小是否为零
c.max_size(); //可容纳元素的最大数量
c.at(idx) ; //返回索引为idx所标示的元素。如果idx越界,抛出out_of_range
c.front() ; //返回第一个元素
c.back(); //返回最后一个元素
c.begin(); //指向第一个元素
c.end(); //指向最后元素的下一位置
c.assign(n , elem); //将n个elem赋值给c
c.assing(beg , end); //将区间[beg;end]中的元素赋值给c;
c.push_back(elem); //在添加元素elem
c.pop_back() ; //删除最后一个元素
c.push_front(elem); //在头部添加元素elem
c.pop_front(); //删除头部一个元素
c.erase(pos); //移除pos位置上的元素
c.insert(pos , elem); //在pos位置插入一个元素elem
c.insert(pos , n , elem); //在pos位置插入n个元素elem
c.clear(); //清空
- sscanf函数
常用于类型转换
sscanf("abc", "%s",buf);
printf("%s", buf);
//结果为abc
sscanf("123 abc", "%d",buf);
printf("%d", buf);
//结果为123
sscanf("123abcABC", "%[1-9a-z]",buf); //或sscanf("123abcABC", "%[^A-Z]", buf);
printf("%s", buf);
//结果为123abc
sscanf("100 abc","%d%n",&m,&n)//%n的意思是调用sscanf已经读出的字符个数
//结果为m=100n=3
sscanf("123 ", "%2s", buf);
printf("%s", buf);
//结果为12
- 建立链表
//建立单链表
#include<bits/stdc++.h>
using namespace std;
struct List
{
int data;
List* next;
};
void createList(List* lst)
{
for(int i=2;i<7;i++)
{
cout<<lst->data<<endl;
List* pNew=new List();
pNew->data=i;
pNew->next=NULL;
lst->next=pNew;
lst=pNew;
}
}
int main()
{
List* lst=NULL;
lst=new List();
lst->data=1;
lst->next=NULL;
createList(lst);
return 0;
}
- 树的三种遍历
#include<iostream>
using namespace std;
struct Node
{
int data;
Node* left;
Node* right;
Node():left(NULL),right(NULL){}//初始
};
void createBiTree(Node* &T)//指针的引用
{
int n;
cin>>n;
if(n==-1)
{
T=NULL;
}
else
{
T=new Node;
T->data=n;
createBiTree(T->left);
createBiTree(T->right);
}
}
//前序遍历二叉树并打印
void preOrder(Node* T)
{
if(T)//根左右
{
cout<<T->data<<" ";
preOrder(T->left);
preOrder(T->right);
}
}
//中序遍历二叉树并打印
void inOrder(Node* T)
{
if(T)//左根右
{
inOrder(T->left);
cout<<T->data<<" ";
inOrder(T->right);
}
}
//后续遍历二叉树并打印
void postOrder(Node* T)
{
if(T)//左右根
{
postOrder(T->left);
postOrder(T->right);
cout<<T->data<<" ";
}
}
int main()
{
Node* T;
createBiTree(T);
cout<<"前序遍历二叉树:"<<endl;
preOrder(T);
cout<<endl;
cout<<"中序遍历二叉树:"<<endl;
inOrder(T);
cout<<endl;
cout<<"后序遍历二叉树:"<<endl;
postOrder(T);
return 0;
}
//input:
//1 2 4 -1 -1 5 -1 -1 3 6 -1 -1 7 -1 -1
//output:
//前序遍历二叉树:
//1 2 4 5 3 6 7
//中序遍历二叉树:
//4 2 5 1 6 3 7
//后序遍历二叉树:
//4 5 2 6 7 3 1
- 指针的引用
用指针或者引用做参数,表示把变量的地址传递给子函数,但是子函数只能修改指针所指变量的值,并不能修改指针的指向。通常,用指针和引用做参数,只是想要修改指针所指变量的值,并没有想修改指针的指向。
如果想用修改指针的指向,即如果指针所指的这块内存在调用子函数结束之后发生了改变,就要用指针的指针,或者指针的引用。 - c_str()
返回一个指向正规C字符串的指针,内容与本字符串相同。
char c[7];
string s="123";
strcpy(c,s.c_str());
int a;
a=atoi(s.c_str());//atoi将字符串转化成数字
- 欧拉回路
一、无向图
每个顶点的度数都是偶数
二、有向图
每个节顶点的入度都等于出度
一、二原理就是每个顶点都要能进去多少次就能出来多少次
//Sample Input
//3 3
//1 2
//1 3
//2 3
//3 2
//1 2
//2 3
//0 0
//Sample Output
//YES
//NO
#include<bits/stdc++.h>
using namespace std;
int mapp[1005][1005],vis[1005],ru[1005];
int n;
void dfs(int a)
{
vis[a]=1;
for(int i=1;i<=n;i++)
if(mapp[a][i]&&!vis[i])
dfs(i);
}
int main()
{
int m;
while(cin>>n>>m&&(n!=0||m!=0))
{
while(m--)
{
int a,b;
cin>>a>>b;
mapp[a][b]=1;
mapp[b][a]=1;
ru[a]++;
ru[b]++;
}
int num=0;
dfs(1);
bool flag=false;
for(int i=1;i<=n;i++)
if(ru[i]%2||!vis[i])
{
flag=true;
break;
}
if(flag)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
memset(mapp,0,sizeof(mapp));
memset(ru,0,sizeof(ru));
memset(vis,0,sizeof(vis));
}
return 0;
}
- unique()函数
功能是元素去重。即序列中所有相邻的重复元素只保留一个
unique(a,b);//从a到b去掉重复
- 深度优先搜索dfs
//1.放入一个节点,起始放入根节点
//2.如果这个节点是第一次出现,则放入堆栈中
//3.判断该节点的子节点是否搜索完成:
//如果是则将该节点出栈,判断该栈是否为空,若为空则结束,否则取栈顶元素,并回放入节点。
//如果不是则取未被搜索的根节点,并回放入节点
#include<bits/stdc++.h>
using namespace std;
vector<vector<int> > tree;//声明一个二维向量
int flag[10];//用于搜索到了节点i的第几个节点
queue<int> M;//声明一个队列
int ar_tree[8]={1,1,1,3,5,3,5,7};
void bfs(int node)
{
int temp;
cout<<node<<" ";
int m_first=M.front();//从队列中取出第一个节点
M.pop();
while(flag[node]<tree[node].size())
{
temp=tree[node][flag[node]];
flag[node]++;
M.push(temp);//把temp加入队列中
}
if(!M.empty())
bfs(M.front());
}
int main()
{
int i,temp;
tree.resize(10);//图中的数共有九个节点
for(i=2;i<=9;i++)//生成树
{
temp=ar_tree[i-2];
tree[temp].push_back(i);//表示第i个节点为第temp个节点的子节点
}
M.push(1);
bfs(1);
return 0;
}
//博主cclplus
- 广度优先搜索bfs
//1.放入一个节点,起始放入根节点
//2.从队列中取出第一个元素,将所取得元素的全部节点加入队列中
//3.判断队列是否为空:
//如果是,则结束
//如果不是,则从队列中取出第一个元素
#include<bits/stdc++.h>
using namespace std;
vector<vector<int> > tree;
int flag[10];
stack<int> stk;
int ar_tree[8]={1,1,1,3,5,3,5,7};
void dfs(int node)
{
cout<<node<<" ";
if (flag[node]==0)
stk.push(node);
int temp;
if(flag[node]<tree[node].size())//判断node的子节点是否搜索完成
{
temp=tree[node][flag[node]];
flag[node]++;
dfs(temp);
}
else//若已经完成
{
stk.pop();//弹出子节点
if(!stk.empty())//若堆栈不为空
{
temp=stk.top();//取此时的栈顶元素,即为node的上一级节点
dfs(temp);
}
}
}
int main()
{
int i,temp;
tree.resize(10);//图中的数共有九个节点
for(i=2;i<=9;i++)
{
temp=ar_tree[i-2];
tree[temp].push_back(i);//表示第i个节点为第temp个节点的子节点
}
dfs(1);
return 0;
}
//博主cclplus
- next_permutation函数–全排列
int main()
{
int a[7]={1,2,3};
do
{
cout<<a[0]<<" "<<a[1]<<" "<<c[2]<<endl;
}while(next_permutation(a,a+3));
return 0;
}
- remove函数
对vector而言1.remove删除的元素放在后面,并未真正的删除函数
remove(vec.begin(),vec.end(),t);
//为要删除元素
2.remove删除函数
vec.erase(remove(vec.begin(),vec.end(),t),vec.end());
//为要删除元素
对list来说remove可以从列表容器中删除与t相等的元素,同时会减小链表的大小
cin>>t;
list.remove(t);
- 二叉树已知先序,中序,后序相互求法
#include<bits/stdc++.h>
using namespace std;
char preOrder[777],inOrder[777],postOrder[777];
void pre(int r1,int l1,int r2,int l2)//已知中序,后序,求先序
{
if(r1>l1)
return;
int p=r2;
int root=postOrder[l1];
cout<<postOrder[l1];
while(inOrder[p]!=root)
p++;
pre(r1,l1-l2+p-1,r2,p-1);//核
pre(l1-l2+p,l1-1,p+1,l2);//心
}
void post(int r1,int l1,int r2,int l2)//已知先序,中序,求后序
{
if(r1>l1)
return;
int p=r2;
int root=preOrder[r1];
while(inOrder[p]!=root)
p++;
post(r1+1,l1-l2+p,r2,p-1);//核
post(l1-l2+p+1,l1,p+1,l2);//心
cout<<preOrder[r1];
}
int main(void)
{
while(cin>>preOrder>>inOrder>>postOrder)
{
int l=strlen(inOrder);
pre(0,l-1,0,l-1);
cout<<endl;
post(0,l-1,0,l-1);
cout<<endl;
cout<<endl;
}
return 0;
}
- 结构体内嵌比较函数bool operator < (const node &x) const {}
struct node
{
int l;
int r;
bool operator <(const node &a)const{
return r<a.r;
}
}a[maxn];
//如果r<a.r,那么就是从小到大排序,但是优先队列的是相反的
struct node
{
int l;
int r;
bool operator <(const node &a)const{
return r>a.r;
}
};
priority_queue<node> q;
//这个优先队列是按r小的优先出队。
也可以用sort(a,a+n,cmp);
但是这种排序的方法比结构体内嵌比较函数的慢很多,sort默认从小到大排列。
- memcpy函数
void *memcpy( void *to, const void *from, size_t count );
函数从from中复制count个字符到to中
将一个字符串数据复制到一块内存
memcpy(target,char,sizeof(char)*N);
将一个字符串数据复制到一块内存的指定位置
memcpy(target+i,char,sizeof(char)*N);