首页 > 代码库 > C++STL 常用 函数 用法(转)
C++STL 常用 函数 用法(转)
http://www.cnblogs.com/duoduo369/archive/2012/04/12/2439118.html
迭代器(iterator)
个人理解就是把所有和迭代有关的东西给抽象出来的,不管是数组的下标,指针,for里面的、list里面的、vector里面的,抽象一下变成了iterator
1 #include <iostream> 2 #include <vector> 3 4 using namespace std; 5 6 int main() 7 { 8 vector<int> v; 9 for(int i = 0; i < 10; ++i )10 {11 v.push_back(i);12 }13 for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)14 {15 cout << *it << " ";16 }17 cout << endl;18 return 0;19 }
求和(<numeric> accumulate)
accumulate(v.begin(),v.end(),0),把从 v.begin() 开始到 v.end()结束所有的元素加到 0上面去
1 #include <iostream> 2 #include <vector> 3 #include <numeric> 4 5 using namespace std; 6 7 int main() 8 { 9 vector<int> v;10 for(int i = 0; i < 10; ++i )11 {12 v.push_back(i);13 }14 for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)15 {16 cout << *it << " ";17 }18 cout << endl;19 cout << accumulate(v.begin(),v.end(),0) << endl;20 return 0;21 }
vector(动态数组)
vector有内存管理的机制,也就是说对于插入和删除,vector可以动态调整所占用的内存空间。
vector相关函数
1 #include <iostream> 2 #include <vector> 3 4 using namespace std; 5 6 int main() 7 { 8 vector<int> v; 9 v.push_back(3); //数组尾部插入310 v.push_back(2);11 v.push_back(1);12 v.push_back(0);13 cout << " 下标 " << v[3] << endl;14 cout << " 迭代器 " << endl;15 for(vector<int>::iterator i = v.begin();i!= v.end();++i)16 {17 cout << *i << " ";18 }19 cout << endl;20 //在第一个元素之前插入111 insert begin+n是在第n个元素之前插入21 v.insert(v.begin(),111);22 //在最后一个元素之后插入222 insert end + n 是在n个元素之后插入23 v.insert(v.end(),222);24 25 for(vector<int>::iterator i = v.begin();i!= v.end();++i)26 {27 cout << *i << " ";28 }29 cout << endl;30 31 vector<int> arr(10);32 for(int i = 0; i < 10; i++)33 {34 arr[i] = i;35 }36 for(vector<int>::iterator i = arr.begin();i!= arr.end();++i)37 {38 cout << *i << " ";39 }40 cout << endl;41 42 //删除 同insert43 arr.erase(arr.begin());44 45 for(vector<int>::iterator i = arr.begin();i!= arr.end();++i)46 {47 cout << *i << " " ;48 }49 cout << endl ;50 51 arr.erase(arr.begin(),arr.begin()+5);52 53 for(vector<int>::iterator i = arr.begin();i!= arr.end();++i)54 {55 cout << *i << " " ;56 }57 cout << endl ;58 return 0 ;59 }
数组转置 (<algorithm> reverse)
reverse(v.begin(),v.end())
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 5 using namespace std; 6 7 int main() 8 { 9 vector<int> v;10 for(int i = 0; i < 10; ++i)11 {12 v.push_back(i);13 }14 for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)15 {16 cout << *it << " ";17 }18 cout << endl;19 20 reverse(v.begin(),v.end());21 22 23 for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)24 {25 cout << *it << " ";26 }27 cout << endl;28 return 0;29 }
排序(<algorithm> sort)
sort(v.begin(),v.end())
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 5 using namespace std; 6 7 bool Comp(const int &a,const int &b) 8 { 9 return a>b;10 }11 12 int main()13 {14 vector<int> v;15 v.push_back(1);16 v.push_back(3);17 v.push_back(2);18 v.push_back(55);19 v.push_back(-1);20 v.push_back(0);21 v.push_back(2);22 v.push_back(3);23 v.push_back(4);24 25 for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)26 {27 cout << *it << " ";28 }29 cout << endl;30 31 //默认升序32 sort(v.begin(),v.end());33 34 35 for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)36 {37 cout << *it << " ";38 }39 cout << endl;40 41 //用降序 需要自定义一个降序函数42 sort(v.begin(),v.end(),Comp);43 44 45 for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)46 {47 cout << *it << " ";48 }49 cout << endl;50 51 return 0;52 }
字符串(<string>)
输入
1 #include<iostream> 2 #include<string> 3 #include<cstdio> 4 5 using namespace std; 6 7 int main() 8 { 9 string s1;10 s1 = "hello";11 12 string s2;13 char s[1024];14 //scanf 输入速度比cin快的多15 //scanf 是C函数,不可以输入string16 scanf("%s",s);17 s2 = s;18 19 cout << s1 << endl;20 cout << s2 << endl;21 22 return 0;23 }
尾部添加字符字符串直接用+号 例如: s += ‘a‘; s += "abc",或者使用append方法,s.append(“123”)
删除 (erase clear)
s.erase(it + 1,it + 4); clear()
1 #include<iostream> 2 #include<string> 3 4 using namespace std; 5 6 int main() 7 { 8 string s; 9 s = "0123456789";10 cout << s << endl;11 12 string::iterator it = s.begin();13 14 //删除s[3]15 s.erase(it+3);16 cout << s << endl;17 18 //删除s[1]~s[3]19 s = "0123456789";20 s.erase(it + 1,it + 4);21 cout << s << endl;22 23 //全部删除24 s.clear();25 cout << "clear : " << s << endl;26 27 return 0;28 }
查找(find)
用find找到string里面第一个要找到元素(char或者串),找到返回数组下标,找不到返回end()迭代器
string和vector有很多相同的东西,比如length(),size(),empty(),reverse(),相对也容易,就不一一说了。
数字化处理(string)
经常会遇到这样一种情况,有一个数字,需要把每一位给提取出来,如果用取余数的方法,花费的时间就会很长,所以可以当成字符串来处理,方便、省时。
例子:求一个整数各位数的和
1 #include<iostream> 2 #include<string> 3 4 using namespace std; 5 6 int main() 7 { 8 string s; 9 s = "123456789";10 int sum = 0;11 for(int i = 0; i < s.size(); ++i)12 {13 switch(s[i])14 {15 case ‘1‘: sum += 1;break;16 case ‘2‘: sum += 2;break;17 case ‘3‘: sum += 3;break;18 case ‘4‘: sum += 4;break;19 case ‘5‘: sum += 5;break;20 case ‘6‘: sum += 6;break;21 case ‘7‘: sum += 7;break;22 case ‘8‘: sum += 8;break;23 case ‘9‘: sum += 9;break;24 }25 }26 27 cout << sum << endl;28 29 return 0;30 }
string与char *
1 #include<iostream> 2 #include<string> 3 #include<cstdio> 4 5 using namespace std; 6 7 int main() 8 { 9 string s_string;10 char s_char[1000];11 scanf("%s",s_char);12 13 s_string = s_char;14 15 //printf输出char* 时用c_str处理16 printf(s_string.c_str());17 cout << endl;18 19 printf("%s",s_char);20 cout << endl;21 22 cout << s_char << endl;23 cout << s_string << endl;24 return 0;25 }
sscanf
1 #include<iostream> 2 #include<string> 3 #include<cstdio> 4 5 using namespace std; 6 7 int main() 8 { 9 string s1,s2,s3;10 char sa[100],sb[100],sc[100];11 sscanf("abc 123 wcd","%s%s%s",sa,sb,sc);12 s1 = sa;13 s2 = sb;14 s3 = sc;15 cout << s1 << " " << s2 << " " << s3 << endl;16 17 //将字符串分离成数字,分隔符为‘,‘‘$‘18 int a,b,c;19 sscanf("4,5$6","%d,%d$%d",&a,&b,&c);20 cout << a << " " << b << " " << c << endl;21 return 0;22 }
string与数值相互转换( sprintf <sstream> )
1 #include<iostream> 2 #include<string> 3 #include<sstream> 4 #include<cstdio> 5 6 using namespace std; 7 8 //c++ 方法 把数转换为string 9 string converToString(double x)10 {11 ostringstream o;12 if( o << x)13 {14 // str()没有‘\0‘ c_str有15 return o.str();16 }17 return "error";18 }19 20 double converFromString(const string &s)21 {22 istringstream i(s);23 double x;24 if( i >> x)25 {26 return x;27 }28 //if error29 return 0.0;30 }31 int main()32 {33 char b[100];34 string s1;35 36 //c语言方法37 sprintf(b,"%d",1987);38 s1 = b;39 cout << s1 << endl;40 41 string s2 = converToString(1954);42 cout << s2 << endl;43 44 string s3 = "202";45 int c = converFromString(s3);46 cout << c << endl;47 48 string s4 = "casacsa6";49 int d = converFromString(s4);50 cout << d << endl;51 52 string s5 = "21abf4";53 int f = converFromString(s5);54 cout << f << endl;55 56 return 0;57 }
set容器
set是用红黑树的平衡二叉索引树的数据结构来实现的,插入时,它会自动调节二叉树排列,把元素放到适合的位置,确保每个子树根节点的键值大于左子树所有的值、小于右子树所有的值,插入重复数据时会忽略。set迭代器采用中序遍历,检索效率高于vector、deque、list,并且会将元素按照升序的序列遍历。set容器中的数值,一经更改,set会根据新值旋转二叉树,以保证平衡,构建set就是为了快速检索(python中的set一旦建立就是一个常量,不能改的)。
multiset,与set不同之处就是它允许有重复的键值。
正反遍历,迭代器iterator、reverse_iterator
1 #include<iostream> 2 #include<set> 3 4 using namespace std; 5 6 int main() 7 { 8 set<int> v; 9 v.insert(1);10 v.insert(3);11 v.insert(5);12 v.insert(2);13 v.insert(4);14 v.insert(3);15 16 //中序遍历 升序遍历17 for(set<int>::iterator it = v.begin(); it != v.end(); ++it)18 {19 cout << *it << " ";20 }21 cout << endl;22 23 for(set<int>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit)24 {25 cout << *rit << " ";26 }27 cout << endl;28 29 return 0;30 }
自定义比较函数,insert的时候,set会使用默认的比较函数(升序),很多情况下需要自己编写比较函数。
1、如果元素不是结构体,可以编写比较函数,下面这个例子是用降序排列的(和上例插入数据相同):
1 #include<iostream> 2 #include<set> 3 4 using namespace std; 5 6 struct Comp 7 { 8 //重载() 9 bool operator()(const int &a, const int &b)10 {11 return a > b;12 }13 };14 int main()15 {16 set<int,Comp> v;17 v.insert(1);18 v.insert(3);19 v.insert(5);20 v.insert(2);21 v.insert(4);22 v.insert(3);23 24 for(set<int,Comp>::iterator it = v.begin(); it != v.end(); ++it)25 {26 cout << *it << " ";27 }28 cout << endl;29 30 for(set<int,Comp>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit)31 {32 cout << *rit << " ";33 }34 cout << endl;35 36 return 0;37 }
2、元素本身就是结构体,直接把比较函数写在结构体内部,下面的例子依然降序:
1 #include<iostream> 2 #include<set> 3 #include<string> 4 5 using namespace std; 6 7 struct Info 8 { 9 string name;10 double score;11 12 //重载 <13 bool operator < (const Info &a) const14 {15 return a.score < score;16 }17 };18 int main()19 {20 set<Info> s;21 Info info;22 23 info.name = "abc";24 info.score = 123.3;25 s.insert(info);26 27 info.name = "EDF";28 info.score = -23.53;29 s.insert(info);30 31 32 info.name = "xyz";33 info.score = 73.3;34 s.insert(info);35 36 for(set<Info>::iterator it = s.begin(); it != s.end(); ++it)37 {38 cout << (*it).name << ":" << (*it).score << endl;39 }40 cout << endl;41 42 for(set<Info>::reverse_iterator rit = s.rbegin(); rit != s.rend(); ++rit)43 {44 cout << (*rit).name << ":" << (*rit).score << endl;45 }46 cout << endl;47 48 return 0;49 }
multiset与set的不同之处就是key可以重复,以及erase(key)的时候会删除multiset里面所有的key并且返回删除的个数。
map
map也是使用红黑树,他是一个键值对(key:value映射),便利时依然默认按照key程序的方式遍历,同set。
1 #include<iostream> 2 #include<map> 3 #include<string> 4 5 using namespace std; 6 7 int main() 8 { 9 map<string,double> m;10 11 //声明即插入12 m["li"] = 123.4;13 m["wang"] = 23.1;14 m["zhang"] = -21.9;15 m["abc"] = 12.1;16 for(map<string,double>::iterator it = m.begin(); it != m.end(); ++it)17 {18 //first --> key second --> value19 cout << (*it).first << ":" << (*it).second << endl;20 }21 cout << endl;22 return 0;23 }
用map实现数字分离
string --> number
之前用string进行过数字分离,现在使用map
1 #include<iostream> 2 #include<map> 3 #include<string> 4 5 using namespace std; 6 7 int main() 8 { 9 map<char,int> m;10 11 m[‘0‘] = 0;12 m[‘1‘] = 1;13 m[‘2‘] = 2;14 m[‘3‘] = 3;15 m[‘4‘] = 4;16 m[‘5‘] = 5;17 m[‘6‘] = 6;18 m[‘7‘] = 7;19 m[‘8‘] = 8;20 m[‘9‘] = 9;21 /*22 等价于23 for(int i = 0; i < 10; ++i)24 {25 m[‘0‘ + i] = i;26 }27 */28 29 string sa;30 sa = "9876543210";31 int sum = 0;32 for( int i = 0; i < sa.length(); ++i)33 {34 sum += m[sa[i]];35 }36 cout << sum << endl;37 return 0;38 }
number --> string
1 #include <iostream> 2 #include <map> 3 #include <string> 4 5 using namespace std; 6 7 int main() 8 { 9 map<int,char> m;10 11 for(int i = 0; i < 10; ++i)12 {13 m[i] = ‘0‘ + i;14 }15 16 int n = 7;17 18 string out = "the number is :";19 cout << out + m[n] << endl;20 21 return 0;22 }
multimap
multimap由于允许有重复的元素,所以元素插入、删除、查找都与map不同。
插入insert(pair<a,b>(value1,value2))
1 #include <iostream> 2 #include <map> 3 #include <string> 4 5 using namespace std; 6 7 int main() 8 { 9 multimap<string,double> m;10 11 m.insert(pair<string,double>("Abc",123.2));12 m.insert(pair<string,double>("Abc",123.2));13 m.insert(pair<string,double>("xyz",-43.2));14 m.insert(pair<string,double>("dew",43.2));15 16 for(multimap<string,double>::iterator it = m.begin(); it != m.end(); ++it )17 {18 cout << (*it).first << ":" << (*it).second << endl;19 }20 cout << endl;21 22 return 0;23 }
至于删除和查找,erase(key)会删除掉所有key的map,查找find(key)返回第一个key的迭代器
deque
deque和vector一样,采用线性表,与vector唯一不同的是,deque采用的分块的线性存储结构,每块大小一般为512字节,称为一个deque块,所有的deque块使用一个Map块进行管理,每个map数据项记录各个deque块的首地址,这样以来,deque块在头部和尾部都可已插入和删除元素,而不需要移动其它元素。使用push_back()方法在尾部插入元素,使用push_front()方法在首部插入元素,使用insert()方法在中间插入元素。一般来说,当考虑容器元素的内存分配策略和操作的性能时,deque相对vectore更有优势。(下面这个图,我感觉Map块就是一个list< map<deque名字,deque地址> >)
插入删除
遍历当然可以使用下标遍历,在这里使用迭代器。
1 #include <iostream> 2 #include <deque> 3 4 using namespace std; 5 6 int main() 7 { 8 deque<int> d; 9 10 //尾部插入11 d.push_back(1);12 d.push_back(3);13 d.push_back(2);14 for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )15 {16 cout << (*it) << " ";17 }18 cout << endl << endl;19 20 //头部插入21 d.push_front(10);22 d.push_front(-23);23 for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )24 {25 cout << (*it) << " ";26 }27 cout << endl << endl;28 29 d.insert(d.begin() + 2,9999);30 for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )31 {32 cout << (*it) << " ";33 }34 cout << endl << endl;35 36 //反方向遍历37 for(deque<int>::reverse_iterator rit = d.rbegin(); rit != d.rend(); ++rit )38 {39 cout << (*rit) << " ";40 }41 cout << endl << endl;42 43 //删除元素pop pop_front从头部删除元素 pop_back从尾部删除元素 erase中间删除 clear全删44 d.clear();45 d.push_back(1);46 d.push_back(2);47 d.push_back(3);48 d.push_back(4);49 d.push_back(5);50 d.push_back(6);51 d.push_back(7);52 d.push_back(8);53 for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )54 {55 cout << (*it) << " ";56 }57 cout << endl;58 59 d.pop_front();60 d.pop_front();61 for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )62 {63 cout << (*it) << " ";64 }65 cout << endl;66 67 d.pop_back();68 d.pop_back();69 for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )70 {71 cout << (*it) << " ";72 }73 cout << endl;74 75 d.erase(d.begin() + 1);76 for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )77 {78 cout << (*it) << " ";79 }80 cout << endl;81 return 0;82 }
list
list<int> l
插入:push_back尾部,push_front头部,insert方法前往迭代器位置处插入元素,链表自动扩张,迭代器只能使用++--操作,不能用+n -n,因为元素不是物理相连的。
遍历:iterator和reverse_iterator正反遍历
删除:pop_front删除链表首元素;pop_back()删除链表尾部元素;erase(迭代器)删除迭代器位置的元素,注意只能使用++--到达想删除的位置;remove(key) 删除链表中所有key的元素,clear()清空链表。
查找:it = find(l.begin(),l.end(),key)
排序:l.sort()
删除连续重复元素:l.unique() 【2 8 1 1 1 5 1】 --> 【 2 8 1 5 1】
bitset
从来没用过,上两幅图吧就:
stack(后进先出)
这个印象深刻,学数据结构的时候做表达式求值的就是用的栈。
1 #include <iostream> 2 #include <stack> 3 using namespace std; 4 5 int main() 6 { 7 8 stack<int> s; 9 s.push(1);10 s.push(2);11 s.push(4);12 s.push(5);13 14 cout << s.size() << endl;15 16 while(s.empty() != true)17 {18 cout << s.top() << endl;19 s.pop();20 }21 return 0;22 }
stack然我唯一费解之处在于,貌似它没有iterator,可以试试s.begin()编译器报错的。
queue(先进先出)
queue有入队push(插入)、出队pop(删除)、读取队首元素front、读取队尾元素back、empty,size这几种方法
priority_queue(最大元素先出)
1 #include <iostream> 2 #include <queue> 3 using namespace std; 4 5 int main() 6 { 7 8 priority_queue<int> pq; 9 10 pq.push(1);11 pq.push(3);12 pq.push(2);13 pq.push(8);14 pq.push(9);15 pq.push(0);16 17 cout << "size: " << pq.size() << endl;18 19 while(pq.empty() != true)20 {21 cout << pq.top() << endl;22 pq.pop();23 }24 return 0;25 }
重载操作符同set重载操作符。
C++STL 常用 函数 用法(转)