Algorithm
参考: https://blog.youkuaiyun.com/yo_bc/article/details/53337839
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
void print(int &elem){ //有无&均可
cout << elem << " ";
}
//qsprt必须用这种格式定义比较函数,像bj定义qsort传入参数会出错
// *和(int *)是同一优先级运算符,但结合方向是从右向左
int cmp(const void *a, const void *b){
return *(int *)a - *(int *)b;
}
int bj(int a, int b){
return a > b;
}
int main(){
int a[] = {0, 3, 9, 1, 4, 8, 5, 2, 6, 7};
/*traverse*/
for_each(a, a+10, print);
cout << endl;
/*swap*/
char x = 'X', y = 'Y';
swap(x, y);
printf("x = %c, y = %c\n", x, y);
/*reverse*/
int a[4]={1,2,3,4};
reverse(a,a+4);
char str[] = "abcdefgh";
reverse(str,str+8); //前闭后开
string s = "abcdefg";
reverse(s.begin(),s.begin()+8);
reverse(s.begin(),s.end());
cout << str << endl;
vector<int> v={1,2,3,4,5};
reverse(v.begin(),v.end());//v的值为5,4,3,2,1
/*sort*/
//快排模板函数,数组下标从0开始,即排序下标为0-9的元素
//qsort,sort时间复杂度都是O(n*log(n)),但实际中sort速度一般比qsort快!!
int a[] = {0, 3, 9, 1, 4, 8, 5, 2, 6, 7};
for_each(a, a+10, print);
qsort(a, 10, sizeof(a[0]), cmp);
// sort(aa, aa+10);
//不传入第三个参数默认sort为升序排序
sort(aa, aa+10, bj);
//struct sort
/*struct node {
int index;
string name;
}q[10];
bool cmpD(node x,node y) { //注意参数类型
return x.index>=y.index;
}
sort(q,q+10,cmpD);*/
/*max min*/
cout << endl << max(66,88) << endl << min(66,88) << endl;
/*unique*/
// sort words alphabetically so we can find the duplicates
sort(words.begin(), words.end());
vector<string>::iterator end_unique = unique(words.begin(), words.end());
words.erase(end_unique, words.end());
//二路归并,头文件algorithm
int ak[] = {1, 9, 5, 4, 7};
int ka[] = {3, 6, 2, 8, 0};
int kk[15];
sort(ak, ak+5);
sort(ka, ka+5);
merge(ak, ak+5, ka, ka+5, &kk[1]);
for_each(ak, ak+5, print);
cout << endl;
for_each(ka, ka+5, print);
cout << endl;
for_each(kk+1, kk+11, print);
cout << endl;
return 0;
}
vector
- 初始化
#include <vector>
vector< typeName > v1; //默认v1为空,故以下的赋值是错误的v1[0]=5;
vector<typeName>v2(v1); 或v2=v1;或vector<typeName> v2(v1.begin(), v1.end());//v2是v1的一个副本,若v1.size()>v2.size()则赋值后v2.size()被扩充为v1.size()。
vector< typeName > v3(n,i);//v3包括n个值为i的typeName类型元素
vector< typeName > v4(n); //v4含有n个值为0的元素
int a[4]={0,1,2,3,3}; vector<int> v5(a,a+5);//v5的size为5,v5被初始化为a的5个值。后一个指针要指向将被拷贝的末元素的下一位置。
vector<int> v6(v5);//v6是v5的拷贝
vector< 类型 > 标识符(最大容量,初始全部值);
- 基本操作
v.push_back(t) //入vector,尾巴
v.pop_back() //出vector,尾巴
v.back() //获取vector尾部元素
v.front() //获取vector头部元素
v.size() //返回容器中数据的个数,
v.empty() //推断vector是否为空
v[n] //返回v中位置为n的元素
v.clear() //删除容器中的全部元素。
- 其他操作
v.resize(2*v.size)
v.resize(2*v.size, 99) //将v的容量翻倍(并把新元素的值初始化为99)
v.insert(pointer,number, content) //向v中pointer指向的位置插入number个content的内容。
v.insert(pointer, content)
v.insert(pointer,a[2],a[4]) //将a[2]到a[4]三个元素插入。
v.erase(pointer1,pointer2) //删除pointer1到pointer2中间(包含pointer1所指)的元素。
Eg.
v5.insert(v5.begin()+1,9); //在第二个位置插入新元素
v5.erase(v5.begin() + 3); //删除第四个元素
v5.insert(v5.begin() + 1, 7,8); //连续插入7个8
v1==v2 //推断v1与v2是否相等。
!=、<、<=、>、>= // 保持这些操作符惯有含义。
vector<typeName>::iterator p=v1.begin( ); //p初始值指向v1的第一个元素。*p取所指向元素的值。对于const vector<typeName>仅仅能用vector<typeName>::const_iterator类型的指针訪问。
p=v1.end( ) //p指向v1的最后一个元素的下一位置。
string
- 初始化
include <string>
string s1; //初始化字符串,空字符串
string s2 = s1; //拷贝初始化,深拷贝字符串
string s3 = "hello world"; //直接初始化,s3存了字符串
string s4(10, 'a'); //s4存的字符串是aaaaaaaaaa
string s5(s4); //拷贝初始化,深拷贝字符串
string s6("hello world"); //直接初始化
string s7 = string(6, 'c'); //拷贝初始化,cccccc
string str , getline(cin, str);//获取整一行
- 基本操作
string s1 = s2 + s3;//将两个字符串合并成一个
string s1 = s2 + "hello world";
s1 = s2;//用一个字符串来替代另一个字符串的对用元素
s.empty()
s.size()
s[n]
s1 == s2, s1!=s2 //大小写敏感
<,<=,>,>= //大小比较
- 判断字符函数
isalpha(c)
islower(c)
isupper(c)
tolower(c)
toupper(c)
isdigit(c)
isspace(c)
isalnum(c) //字母或者数字
map
key - value的对应
参考: https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html
- 基本操作
#include <map>
map<int,string> mapStudent;
/*遍历*/
//method 1
map<int,string>::iterator iter;
for(iter=mapStudent.begin(); iter!= mapStudent.end();iter++){
cout << iter->first << " " << iter->second << endl;
}
//method 2
int mapSize = mapStudent.size();
for(int i= 1; i <= mapSize;i++){
cout << mapStudent[i] << endl;
}
/*插入操作*/
//method 1 : pair插入 (VC-#pragma warning (disable:4786) )
mapStudent.insert(pair<int, string>(1,"1111");
mapStudent.insert(pair<int, string>(2,"2222");
mapStudent.insert(pair<int, string>(3,"3333");
//method 2: value_type数据
mapStudent.insert(map<int, string>::value_type(1,"1111"));
mapStudent.insert(map<int, string>::value_type(2,"2222"));
mapStudent.insert(map<int, string>::value_type(3,"3333"));
//method 3: 数组插入
mapStudent[1]="1111";
mapStudent[2]="2222";
mapStudent[3]="3333";
// 第一种和第二种方法效果一样, 当key一样的时候, 不能插入
//而数组的方式可以, 后面覆盖前面的值
//如何判断插入成果
pair<map<int, string>::iterator, bool> insertState;
insertState = mapStudent.insert(map<int, string>::value_type(1,"1111"));
if(insertState.second == true) //insert success!
else // insert fail!
/*查找*/
map<int, string>::iterator iter;
iter= mapStudent.find(1);
if(iter != mapStudent.end()) cout << iter->second<< endl;
else cout <<"Can't find" << endl;
/*删除*/
//method 1
map<int, string>::iterator iter;
iter = mapStudent.find(1);
mapStudent.erase(iter);
// method 2
int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0
mapStudent.erase( mapStudent.begin(), mapStudent.end() ); //一下代码把整个map清空
- 排序问题
#include <iostream>
#include <string>
#include <map>
using namespace std;
typedef struct tagStudentinfo
{
int niD;
string strName;
bool operator < (tagStudentinfo const& _A) const
{ //这个函数指定排序策略,按niD排序,如果niD相等的话,按strName排序
if(niD < _A.niD) return true;
if(niD == _A.niD)
return strName.compare(_A.strName) < 0;
return false;
}
}Studentinfo, *PStudentinfo; //学生信息
int main()
{
int nSize; //用学生信息映射分数
map<Studentinfo, int>mapStudent;
map<Studentinfo, int>::iterator iter;
Studentinfo studentinfo;
studentinfo.niD = 1;
studentinfo.strName = "student_one";
mapStudent.insert(pair<Studentinfo, int>(studentinfo, 90));
studentinfo.niD = 2;
studentinfo.strName = "student_two";
mapStudent.insert(pair<Studentinfo, int>(studentinfo, 80));
for (iter=mapStudent.begin(); iter!=mapStudent.end(); iter++)
cout<<iter->first.niD<<' '<<iter->first.strName<<' '<<iter->second<<endl;
return 0;
}
set
set与vector类似, 但是删除了重复,以及自动排序了
#include<set>
#include<iostream>
using namespace std;
int main()
{
set<int>s;
set<int> s1{9,8,1,2,3,4,5,5,5,6,7,7 }; //自动排序,从小到大,剔除相同项
set<string> s2{ "hello","sysy","school","hello" }; //字典序排序
s1.insert(9); //有这个值了,do nothing
s2.insert("aaa"); //没有这个字符串,添加并且排序
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
s.insert (x);
}
set<int>::iterator it;
for(it=s.begin ();it!=s.end ();it++)
{
printf("%d\n",*it);
}
//s.end()没有值
cout<<"s.begain() "<<*s.begin ()<<endl;
//lower_bound()--返回指向大于(或等于)某值的第一个元素的迭代器
cout<<"lower_buond 3 "<<*s.lower_bound (3)<<endl;
//upper_bound()--返回大于某个值元素的迭代器
cout<<"upper_bound 3 "<<*s.upper_bound (3)<<endl;
//find()--返回一个指向被查找到元素的迭代器
cout<<"find() 3 "<<*s.find (3)<<endl;
int a[] = {1,2,3};
//Example:
/*set<int> s1(a,a+3);
set<int>::iterator iter;
if((iter = s1.find(2)) != s1.end())
{
cout<<*iter<<endl;//输出为2
}
*/
cout<<"s.size() "<<s.size ()<<endl;
return 0;
/*删除*/
s.erase(iterator) ,删除定位器iterator指向的值
s.erase(first,second),删除定位器first和second之间的值
s.erase(key_value),删除键值key_value的值
}
- 自定义比较函数:
- 元素不是结构体:
struct myComp
{
bool operator()(const your_type &a,const your_type &b)
[
return a.data-b.data>0;
}
}
set<int,myComp>s;
......
set<int,myComp>::iterator it;
- 元素是结构体:
struct Info
{
string name;
float score;
//重载“<”操作符,自定义排序规则
bool operator < (const Info &a) const
{
//按score从大到小排列
return a.score<score;
}
}
set<Info> s;
......
set<Info>::iterator it;
list
list就是链表.
list是一个双向链表,而单链表对应的容器则是foward_list。
list即双向链表的优点是插入和删除元素都比较快捷,缺点是不能随机访问元素。
初始化方式就大同小异了,跟vector基本一样。要想用list先加个头文件list。
#include <iostream>
#include <list>
#include <string>
using namespace std;
template <typename T>
void showlist(list<T> v)
{
for (list<T>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it;
}
cout << endl;
}
int main()
{
list<int> l1{ 1,2,3,4,5,5,6,7,7 };
showlist(l1);
list<double> l2;
list<char> l3(10);
list<int> l4(5, 10); //将元素都初始化为10
showlist(l4);
system("pause");
return 0;
}
值得注意的是,list容器不能调用algorithm下的sort函数进行排序,因为sort函数要求容器必须可以随机存储,而list做不到。所以,list自己做了一个自己用的排序函数,用法如下:
list<int> l1{ 8,5,7,6,1,2,3,4,5,5,6,7,7 };
l1.sort();
stack
- 基本操作
#include <stack>
s.push(x);
s.pop(). //注意:出栈操作只是删除栈顶的元素,并不返回该元素。
s.top();
s.empty(). //当栈空时返回true。
s.size();
s1==s2 //若成立,表明s1中的每个元素都等于s2的对应元素,返回true或是false
queue
- 基本操作
#include<cstdlib>
#include <queue>
queue<int>q1;
queue<double>q2;
q.push(x) //将x元素接到队列的末端;
q.pop() //弹出队列的第一个元素,并不会返回元素的值;
q.front()//访问队首元素
q.back();//访问队尾元素
q.size();//访问队中的元素个数