主要通过实例来解释C++一些STL库的用法,也可以当作手册阅读。本文的样例代码默认使用std名称空间。会持续更新(有空就会加一些)
主要内容包括:string,stack,queue,list,vector,map,deque,set,pair的用法,和algorithm中的常用函数。
string 是C++用来高效处理字符串的类,封装了很多常用的字符串处理方法。下列样例str开头的变量都是string类,cstr表示C风格字符串.
#include
使用是要引入该库
string str_a = "this is a string"; //this is a string
string str_b(str_a); // this is a string
char cstr[20] = "this is a string"; //this is a string
string str_c(cstr); //this is a string
string str_d(cstr,3); //thi
string str_e(str_a,3); //s is a string
string str_f(10,'#'); //##########
length()
不是length
(python)string str_a = "12345";
string str_b = "";
cout << str_a.size() << endl; // size=5
cout << str_a.length() << endl; // length=5
cout << str_b.size() << endl; // size=0
cout << str_b.max_size() << endl; // max_size=9223372036854775807
cout << str_b.capacity() << endl; // capacity=15
比较操作符: >, >=, <, <=, ==, !=
比较算法:对于两个字符串开始,从前往后遍历字符,对相同位置上的不同字符按照字典序比较得出大小。
compare()方法
支持多参数处理,支持用索引值和长度定位子串进行比较,前面减去后面的ASCII码,>0返回1,<0返回-1,相同返回0
string str_a = "12345";
string str_b = "123456";
string str_c = "12346";
string str_d = " 123456";
string str_e = " 123466";
char cstr[20] = " 123456" ;
cout << (str_a > str_b)<< endl; // 12345 > 123456 false
cout << (str_a > str_c)<< endl; // 12345 > 12346 false
cout <<str_a.compare(str_a) << endl; // 12345 cmp 12345 0
cout <<str_a.compare(str_b) << endl; // 12345 cmp 123456 -1
cout <<str_d.compare(2,5,str_a) << endl; // 12345 cmp 12345 0
cout <<str_d.compare(2,5,str_e,2,5) << endl; // 12345 cmp 12346 -1
cout <<str_d.compare(2,5,cstr+2,5) << endl; // 12345 cmp 12345 0
string str_a = "12345";
string::iterator iter = str_a.begin();
for(; iter!=str_a.end();iter++){
cout<<*iter;
}
cout<<endl; // 12345
string::reverse_iterator iter2 = str_a.rbegin(); //注意这里用reverse_iterator
for(; iter2!=str_a.rend();iter2++){
cout<<*iter2;
}
cout<<endl; // 54321
for(int i=0;i<str_a.size();i++){
cout<<str_a[i];
}
cout<<endl;// 12345
//插入
string str="12345";
str.push_back('6');
str.push_back('8');
cout<<str<<endl; // 1234568
str.insert(str.begin()+6,'7');
cout<<str<<endl; // 12345678
//拼接
//方法一:append()
string s1 = "abc";
s1.append("def");
cout<<s1<<endl; // abcdef
// 方法二:+ 操作符
string s2 = "abc";
string s3 = "def";
s2 += s3;
cout<<s2<<endl; // s2:abcdef
// 删除
string s1 = "123456789";
string s2 = "123456789";
string s3 = "123456789";
s1.erase(s1.begin() + 1);
s2.erase(s2.begin() + 1, s2.end() - 2);
s3.erase(1,6);
cout<<s1<<endl; // 13456789
cout<<s2<<endl; // 189
cout<<s3<<endl; // 189
//替换
string s1("hello,world!"),s2("hello,world!"),s3("hello,world!");
s1.replace(6, 5, "girl"); // 结果:hello,girl.
s2.replace(6, 5, 4, 'p'); // 结果:hello,pppp!
s3.replace(s3.begin(), s3.begin() + 5, "boy"); // 结果:boy,girl.
cout<<s1<<endl<<s2<<endl<<s3<<endl;
string s = "ABCDEFG";
for( int i = 0; i < s.size(); i++ )
{
s[i] = tolower(s[i]);
}
cout << s << endl; //abcdefg
transform(s.begin(), s.end(), s.begin(), ::toupper);
cout << s << endl; //"ABCDEFG"
transform(s.begin(), s.end(), s.begin(), ::tolower);
cout << s << endl; //"abcdefg"
string s("this is a buct bird.");
//字符串查找-----找到后返回首字母在字符串中的下标
// 1. 查找一个字符串
cout << s.find("buct") << endl; // 结果是:10
cout << int(s.find("ttt")) << endl; // 结果是:-1
// 2. 从下标为6开始找字符'i',返回找到的第一个i的下标
cout << s.find('i', 6) << endl; // 结果是:16
// 3. 从字符串的末尾开始查找字符串,返回的还是首字母在字符串中的下标
cout << s.rfind("buct") << endl; // 结果是:10
// 4. 从字符串的末尾开始查找字符
cout << s.rfind('i') << endl; // 结果是:16
// 5. 在该字符串中查找第一个属于字符串s的字符
cout << s.find_first_of("13br98") << endl; // 结果是:10("b")
// 6. 在该字符串中查找第一个不属于字符串s的字符,先匹配dog,然后bird匹配不到,所以打印4
cout << s.find_first_not_of("hello dog 2006") << endl; // 结果是:0
// 7. 在该字符串从后往前查找第一个属于字符串s的字符
cout << s.find_last_of("13r98") << endl; // 结果是:17
// 8. 在该字符串从后往前查找第一个不属于字符串s的字符,先匹配tac,然后空格匹配不到,所以打印21
cout << s.find_last_not_of("teac") << endl; // 结果是:19
string a = " this is yzzer ha! ";
//去除前后空额
a.erase(0,a.find_first_not_of(' '));
a.erase(a.find_last_not_of(' ')+1);
cout<<a<<endl; //结果是: "this is yzzer ha!"
//分割字符串函数
vector<string> split(string target, string split_c = " "){//默认按空格来分割
int index = 0;
vector<string> split_list;
while(index < target.size()){
int split_pos = target.find_first_of(split_c, index);
if(split_pos == -1){ //找不到分隔符
break;
}
if(split_pos != index) //连续的分隔符
split_list.push_back(target.substr(index,split_pos - index));
index = split_pos + 1;
}
return split_list;
}
/截取字符串
string number = "0123456789";
cout<< number.substr(3,4) <<endl; // 3456
//按符号分割
vector<string> v = split("hahahah,lalalala,yzzer buct",", ");
for(auto i:v){
cout<<i<<endl;
}
/*
hahahah
lalalala
yzzer
buct
*/
使用algorithm 的sort API
sort(iterator_begin, iterator_end)
string number = "949164461891615161";
sort(number.begin(),number.end());
cout<<number<<endl; //111111444566668999
number = "949164461891615161";
sort(number.begin(),number.begin()+5); // 949164
cout<<number<<endl; //146994461891615161
//int 转 string
int a = 123456;
string str_a = to_string(a);
cout<<str_a[0]<<endl; //1
// string 转 int 1
string str_b = "-12345";
int b = atoi(str_b.c_str());
cout<<b<<endl; //-12345
// string 转 int 2
string str_c = "-13456";
istringstream is(str_c);
int c;
is>>c;
cout<<c<<endl; //-13456
栈是一个先进后出的受限的线性结构容器(FILO),提供的操作较少。
C++的stack容器是基于底层的容器实现的,底层的结构可以是vector,list,deque,默认是deque。
#include
使用时引入该库
stack可以用其他容器初始化,但前提是底层容器和用于初始化的容器类型相同。
stack<int> num_stack_defaut; //使用默认底层容器 一般来说够用了
//list作为底层容器
list<int> mylist(3,123); // 从左到右123 123 123
mylist.push_back(11);
mylist.push_back(22);
mylist.push_back(33); // mylist 从左到右 123 123 123 11 22 33
stack<int,list<int>> num_stack_list(mylist); //只能使用list初始化
// 从栈顶到栈尾 33 22 11 123 123 123
//vector作为底层容器
vector<int> myvector(3,123); // 从左到右123 123 123
myvector.push_back(11);
myvector.push_back(22);
myvector.push_back(33); // mylist 从左到右 123 123 123 11 22 33
stack<int,vector<int>> num_stack_vector(myvector); //只能使用vector初始化
// 从栈顶到栈尾 33 22 11 123 123 123
一般来说最后一个不常用。
// 用模板语法实现的打印栈 (从栈顶到栈底)
void print_stack(stack<T,container> ss){
cout<<"(size:"<<ss.size()<<')'; //获取栈有多少元素
while(!ss.empty()){ //判断栈是否为空
cout<<ss.top()<<' '; //获取栈顶元素
ss.pop(); //弹出栈顶元素
}
cout<<endl;
}
stack<int> num_stack;
num_stack.push(1);// 入栈
num_stack.push(2);// 2会在1之上
num_stack.push(3);
num_stack.push(4);
print_stack(num_stack); // (size:4)4 3 2 1
stack<int> num_stack2;
num_stack2.push(4);
num_stack2.push(5);
num_stack2.push(6);
print_stack(num_stack2); // (size:3)6 5 4
//交换两个栈 必须两个栈的底层容器相同
num_stack.swap(num_stack2);
print_stack(num_stack); // (size:3)6 5 4
print_stack(num_stack2); // (size:4)4 3 2 1
队列是满足FIFO的线性结构。STL的queue模板提供了两个模块 queue循环队列和priority_queue优先队列/堆
#include
使用时引入
queue numQueue; // 声明
for(int i=0;i<5;i++){
numQueue.push(i);
cout<
类的方法和queue大部分一致,区别是声明和使用时的注意.
struct number{
int num;
number(int n=0){
num = n;
}
// 小根堆重载<
bool operator<(const number &a)const{
return num < a.num;
}
//大根堆重载>
bool operator>(const number &a)const{
return num > a.num;
}
};
priority_queue<number> q1; //大根堆(堆顶值最大)
priority_queue<number,vector<number>,greater<number> > q2;// 小根堆(堆顶值最小)
for(int i=0;i<10;i++){
srand(i);
q1.push(number(rand()));
q2.push(number(rand()));
}
cout<<"size:"<<q1.size()<<endl;
//size:10
while(!q1.empty()){
cout<<q1.top().num<<' ';
q1.pop();
}
cout<<endl;
// 68 64 61 58 54 51 48 45 41 38
// 降序输出,每次取出的是最大值
while(!q2.empty()){
cout<<q2.top().num<<' ';
q2.pop();
}
cout<<endl;
// 6151 6673 7196 7719 17422 17945 18467 28170 28693 29216
// 升序输出 每次取出的是最小值