STL:Standard template library,包含了容器、迭代器、函数对象和算法。
与数组类似,可以存储若干个值
容器中每一个值的类型都是相同的
常用的容器:vector、valarray
可以用来遍历容器中的值
类似于函数的对象,可以是类对象或函数指针
排序
查找
2.迭代器(Iterator)基础
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, const char * argv[]) {
// 迭代器(Iterator)基础
//1. 回顾一下vector的基本功能
//2. 向vector追加值
//3. 什么是迭代器
//4. 使用迭代器获取vector中特定位置的值
//5. 使用begin()和end()
//6. 利用迭代器枚举vector中所有的值
//7. 删除vector中特定区间的值
//8. 在vector中特定的位置插入一个或一组值
// vector的基本功能
/*
vector是STL中的一个容器,用于存储若干个值
1. vector可以像数组一样,使用[n]来引用特定位置的值
2. size方法:获取vector中值的个数
3. swap方法:交换容器的内容
4. begin和end方法:来获取首、尾两个迭代器
*/
vector<int> ages;
ages.push_back(20);
ages.push_back(30);
ages.push_back(40);
ages.push_back(50);
ages.push_back(60);
// cout << ages.size() << endl; // 5
// ages.pop_back(); // 虽然60弹出了,但只改变了size的大小(尾指针),值还在vector之中
// cout << ages[4] << endl; // 60
// cout << ages.size() << endl; // 4
// ages.push_back(100); // 从弹出那个位置开始送入值
// cout << ages[4] << endl; // 100
// 什么是迭代器
/*
迭代器是一个广义的指针,用于指向容器中当前的值。可以使用++、--、+、-来移动指针
typedef iterator
*/
// 使用迭代器来获取vector特定位置的值
vector<int>::iterator it;
it = ages.begin(); // 指向vector首元素
cout << *it << endl; // 20
it++;
cout << *it << endl; // 30
cout << *(it + 2) << endl; // 50
// begin和end方法
/*
begin指向了容器的第一个元素的地址
end指向了容器最后一个元素的下一个元素的地址
*/
it = ages.end();
cout << *(it) << endl; // 0
cout << *(it - 1) << endl; // 60
auto it1 = ages.begin(); // auto会自动将it1识别为vector中的迭代器,这样就省去了定义迭代器的步骤
cout << *it1 << endl;
// 枚举vector中所有的值
// 传统的方法
for(int i = 0; i < ages.size(); i++)
{
cout << ages[i] << " ";
}
cout << endl;
// 迭代器枚举vector中的所有的值
for(auto it = ages.begin();it != ages.end();it++) // for(初始化;终止条件;自加)
{
cout << *it << " ";
}
cout << endl; // 20 30 40 50 60
// 7. 删除vector中特定区间的值
// 删除第3个值
ages.erase(ages.begin() + 2);
for(auto it = ages.begin();it != ages.end();it++)
{
cout << *it << " ";
}
cout << endl; // 20 30 50 60
// 删除一个区间的值
ages.erase(ages.begin(), ages.begin() + 3); // 删除第1个到第4个元素,包含第1个,不包含第4个
for(auto it = ages.begin();it != ages.end();it++)
{
cout << *it << " ";
}
cout << endl; // 60
// 8. 在vector中特定的位置插入一个或一组值
ages.insert(ages.begin(), 10); // 方法insert的第一个参数是迭代器,不是索引值
ages.insert(ages.end(), 30);
for(auto it = ages.begin();it != ages.end();it++)
{
cout << *it << " ";
}
cout << endl; // 10 60 30
vector<int> ages1;
ages1.push_back(100);
ages1.push_back(200);
ages1.push_back(300);
// 将ages1中的一个区间的值,插入到ages的指定位置
ages.insert(ages.begin(), ages1.begin() + 1, ages1.end()); // 第一个参数是被插入的vector的迭代器,第二、三个参数是要插进去的vector的迭代器
for(auto it = ages.begin();it != ages.end();it++)
{
cout << *it << " ";
}
cout << endl; // 200 300 10 60 30
return 0;
}
3.用于替代for语句的for_each函数
#include <iostream>
#include <vector>
using namespace std;
class Person
{
public:
int code;
string name;
Person(int code, string name)
{
this->code = code;
this->name = name;
}
};
void eachPerson(const Person& person)
{
//person.code = 300; // 传入参数的类型如果不加const,则这里可以进行一些修改
cout << "code:" << person.code << " name:" << person.name << endl;
}
int main(int argc, const char * argv[]) {
// for_each函数
vector<Person> persons;
persons.push_back(Person(10, "Bill"));
persons.push_back(Person(20, "Mike"));
persons.push_back(Person(30, "John"));
for(auto it = persons.begin(); it != persons.end(); it++) // persons.begin()返回的是一个对象
{
cout << "code:" << it->code << " name:" << it->name << endl;
}
for_each(persons.begin(), persons.end(), eachPerson); // 参数三要传入一个函数
/* for(auto it = persons.begin(); it != persons.end(); it++)
{
cout << "code:" << it->code << " name:" << it->name << endl;
}*/
return 0;
}
4.用于随机排列容器中元素值的random_shuffle函数
#include <iostream>
#include <vector>
using namespace std;
void eachStr(string str)
{
cout << str << endl;
}
int main(int argc, const char * argv[]) {
// 随机排列容器元素的函数:random_shuffle
vector<string> names;
names.push_back("Bill");
names.push_back("Mike");
names.push_back("John");
names.push_back("Mary");
for_each(names.begin(), names.end(), eachStr); // Bill Mike John Mary 每遍历到一个值,就执行一次eachStr
random_shuffle(names.begin(), names.end()); // 随机排列容器中的元素
for_each(names.begin(), names.end(), eachStr); // Bill Mary John Mike
random_shuffle(names.begin(), names.end());
for_each(names.begin(), names.end(), eachStr); // 结果又会不同
return 0;
}
5.用于对容器中元素值排序的sort函数
#include <iostream>
#include <vector>
using namespace std;
class Person
{
public:
int code;
Person(int code)
{
this->code = code;
}
};
// 在C++中,只能对自己定义的类进行操作符重载
bool operator<(const Person& p1, const Person& p2) // 可以通过重载小于号,来改变sort的排序规则
{
// if(p1.code <= p2.code) // 升序
if(p1.code >= p2.code) // 降序
return true;
else
return false;
}
bool comparePerson(const Person& p1, const Person& p2)
{
if(p1.code <= p2.code) // 升序
//if(p1.code >= p2.code) // 降序
return true;
else
return false;
}
bool compareInt(int n1, int n2)
{
// if(n1 <= n2) // 升序
if(n1 >= n2) // 降序
return true;
else
return false;
}
int main(int argc, const char * argv[]) {
// 用于对容器中元素值排序的sort函数
vector<int> numbers;
numbers.push_back(10);
numbers.push_back(5);
numbers.push_back(20);
for(auto it = numbers.begin(); it!=numbers.end();it++)
{
cout << *it << " "; // 空格隔开
}
cout << endl; // 10 5 20
// sort(numbers.begin(), numbers.end()); // 排序后默认按照升序 5 10 20排列
sort(numbers.begin(), numbers.end(), compareInt); // 可以在sort参数三的位置,传入一个比较器
for(auto it = numbers.begin(); it!=numbers.end();it++)
{
cout << *it << " ";
}
cout << endl;
vector<Person> persons;
persons.push_back(Person(20));
persons.push_back(Person(10));
persons.push_back(Person(30));
for(auto it = persons.begin(); it != persons.end();it++)
{
cout << it->code << " ";
}
cout << endl; // 20 10 30
// sort(persons.begin(), persons.end()); // 30 20 10,经过操作符重载之后,将默认的升序变为了降序
sort(persons.begin(), persons.end(),comparePerson);
for(auto it = persons.begin(); it != persons.end();it++)
{
cout << it->code << " ";
}
cout << endl;
return 0;
}
6.用于查找容器中元素值的find函数
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, const char * argv[]) {
// 用于查找容器中元素值的find函数
vector<string> names;
names.push_back("Bill");
names.push_back("Mike");
names.push_back("Mike");
names.push_back("Mary");
vector<string>::iterator it = find(names.begin(), names.end(), "Mike1"); // 第一、二个参数定义查找范围,第三个参数写要查找的值
if(it != names.end()) // 如果等于names.end,说明到末尾了还没找到
{
cout << "已经找到." << endl;
cout << *it << endl;
}
else
{
cout << "未找到." << endl;
}
return 0;
}
7.用于复制容器元素值的copy函数
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, const char * argv[]) {
// copy函数:用于将一个容器中的元素值复制到另一个容器中
vector<string> names;
names.push_back("Bill");
names.push_back("Mike");
names.push_back("John");
names.push_back("Mary");
vector<string> names1(4); // 这里比4大也可以,使用copy前,要提前给目标数组分配内存空间
copy(names.begin(), names.end(), names1.begin()); // 参数12指定数据源要复制的内容的范围,参数3指定要复制到的目标位置
for(auto v:names1) // 用for输出vector中的所有元素的写法
{
cout << v << endl; // Bill Mike John Mary
}
return 0;
}
8.枚举容器中元素的3种方法
#include <iostream>
#include <vector>
using namespace std;
void printNumber(int value)
{
cout << "for_each:" << value << endl;
}
int main(int argc, const char * argv[]) {
// 枚举容器中元素值的3种方法
vector<int> numbers;
numbers.push_back(10);
numbers.push_back(5);
numbers.push_back(20);
// 第1种方法
for(auto it = numbers.end() - 1; it != numbers.begin() - 1;it--) // 这样是从后往前数,此时要注意从numbers.end() - 1开始,从numbers.begin() - 1结束,因为for的范围取前不取后
{
cout << *it << endl; // 20 5 50
}
// 第2种方法,只能从前往后数
for_each(numbers.begin(), numbers.end(), printNumber); // 打印 for_each:10 for_each:5 for_each:20
// 第3种方法
// C++ 11 基于范围的for循环
for(auto n:numbers) // n不是迭代器
{
cout << "基于范围的for循环:" << n << endl; // 10 5 20
}
return 0;
}
9.将STL算法用于非STL容器
#include <iostream>
#include <vector>
using namespace std;
bool compareInt(int n1, int n2)
{
if(n1 >= n2)
return true; // 降序
else
return false;
}
int main(int argc, const char * argv[]) {
// 将STL算法用于非STL容器
// sort、copy等都是基于迭代器实现的
// 基础理论:指针 = 迭代器
int values[] {4,5,1,7,-20};
size_t size = sizeof(values)/sizeof(int);
sort(values, values + size); // 传入的是指针
for(auto v:values)
{
cout << v << " ";
}
cout << endl; // -20 1 4 5 7
sort(values, values + size, compareInt);
for(auto v:values)
{
cout << v << " ";
}
cout << endl; // 7 5 4 1 -20
vector<int> v_values(5); // 使用copy前要预先分配空间
copy(values, values+size, v_values.begin()); // STL容器和非STL容器混合使用
for(auto v:v_values)
{
cout << v << " ";
}
cout << endl; // 7 5 4 1 -20
return 0;
}
|