C++ STL容器篇(一) day12

C++ STL容器篇(一) day12

STL标准模板类型库

  • 容器:数据结构的封装
  • 迭代器:迭代器是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址
  • 算法: 解决问题的具体描述

STL(array)

  • array其实就是定长数组,array是一个模板类,可以存储任何类型
  • array模板是一个类模板,所以他就是一个数据类型
  • 所以数据能做的,它都可以做
    • 当做函数参数
    • 当做函数返回值
    • 当做类的数据成员
  • 具体array库函数看官方文档:array官方手册
#include <array>
#include <iostream>
void testCreateArray() 
{
	std::array<int, 3> arr;
	std::array<std::string, 3> str;
	std::array<double, 3> dNum;
	//列表数据做初始化
	std::array<int, 3> iNum = {1,2,3};
}
void operation() 
{
	//基本操作
	std::array<int, 3> arr = {1,2,3};
	//for (int i = 0; i < 3; i++) 
	//{
	//	std::cin >> arr[i];
	//}
	for (auto v : arr) 
	{
		std::cout << v << " ";
	}
	std::cout << std::endl;
	//其他操作
	//万金油
	//empty: return curSize==0;  返回false表示不为空
	std::cout <<"判断是否为空:" << arr.empty() << std::endl;
	std::cout << "当前元素个数:" << arr.size() << std::endl;
	//注意点: end是容器最后一个位置,不是最后一个元素的位置
	std::cout << "第一个元素:" << arr.front() <<" "<<*arr.begin() << std::endl;
	std::cout << "最后一个元素:" << arr.back() <<" "<<*(arr.end()-1) << std::endl;
	//最大元素个数
	std::cout << "max_size:" << arr.max_size() << std::endl;
	for (int i = 0; i < arr.size(); i++) 
	{
		//获取当前下标下面的值
		std::cout << arr.at(i) << " ";
	}
	std::cout << std::endl;
	//内置迭代器: begin() end()
	std::array<int, 3>::iterator iter;
	for (iter = arr.begin(); iter != arr.end(); iter++) 
	{
		std::cout << *iter << " ";
	}
	std::cout << std::endl;

	std::array<int, 3>::const_iterator c_iter;
	for (c_iter = arr.cbegin(); c_iter != arr.cend(); c_iter++)
	{
		std::cout << *c_iter << " ";
	}
	std::cout << std::endl;
	std::array<int, 3>::reverse_iterator r_iter;
	//rbegin(): 最后一个元素的位置
	//从后往前打印
	for (r_iter = arr.rbegin(); r_iter != arr.rend(); r_iter++)
	{
		std::cout << *r_iter << " ";
	}
	std::cout << std::endl;
	std::array<int, 3>::const_reverse_iterator cr_iter;
	for (cr_iter = arr.crbegin(); cr_iter != arr.crend(); cr_iter++)
	{
		std::cout << *cr_iter << " ";
	}
	std::cout << std::endl;
	//其他函数
	/*
		成员函数	说明
		data	获取第一个元素的地址。
		fill	将所有元素替换为指定值。
		swap	交换两个容器的内容。		
	*/
	std::array<std::string, 3> str;
	str.fill("coolmoying");
	for (auto v : str) 
	{
		std::cout << v << std::endl;
	}
	std::string* pstr = str.data();
	std::cout << *pstr << std::endl;

	std::array<int, 3> one = {1,2,3};
	//默认初始化为0
	std::array<int, 3> two = {5,5};
	one.swap(two);
	for (auto v : one) 
	{
		std::cout << v << " ";
	}
	std::cout << std::endl;
}


std::array<int,3> printArray(const std::array<int, 3>& value) 
{
	for (auto v : value) 
	{
		std::cout << v << " ";
	}
	std::cout << std::endl;
	return value;
}
class SqList 
{
public:
	SqList() :m_sqlist({0}),m_size(0)
	{

	}
	void push_back(int data) 
	{
		m_sqlist[m_size++] = data;
	}
	void print() 
	{
		for (int i = 0; i < m_size; i++) 
		{
			std::cout << m_sqlist[i] << " ";
		}
	}
protected:
	std::array<int, 100> m_sqlist;
	int m_size;
};


void arrayAsData() 
{
	//新标准中创建初始化 =可以省略
	std::array<int, 3> num{ 1,2,3 };
	printArray(num);
	printArray(printArray(printArray(num)));
	SqList sqlist;
	sqlist.push_back(1);
	sqlist.push_back(2);
	sqlist.print();
}

//容器操作用户数据,唯一的难点是在运算符重载
class MM 
{
public:
	MM(std::string name = "", int age = 0) :m_name(name), m_age(age) {}
	void printMM() 
	{
		std::cout << m_name << " " << m_age ;
	}
	friend std::istream& operator>>(std::istream& in, MM& object) 
	{
		std::cout << "input MM info:";
		in >> object.m_name >> object.m_age;
		return in;
	}
	friend std::ostream& operator<<(std::ostream& out, const MM& object) 
	{
		out << object.m_name << " " << object.m_age;
		return out;
	}
protected:
	std::string m_name;
	int m_age;
};

void OperationUserData()
{
	std::array<MM, 3> mm;
	mm[0] = MM("小美", 18);
	std::cin >> mm[1];
	MM girl = { "小瓜", 18 };
	mm[2] = girl;
	for (auto v : mm) 
	{
		//v.printMM();
		//管理自定义类型必须要去做运算符重载
		//有些函数是需要重载其他运算符的
		std::cout << v << std::endl;
	}
	std::cout << mm.max_size() << std::endl;


}

//array嵌套
void arrayNest() 
{
	std::array<std::array<int, 3>, 4> arr = {1,2,3,4,5,6,7,8,9,10,11,12};
	//如果打开读起来比较难懂的,起别名替换
	using Type = std::array<int, 3>;
	std::array<Type, 4> arr2;

	for (int i = 0; i < arr.size(); i++) 
	{
		for (int j = 0; j < arr[i].size();j++) 
		{
			std::cout << arr[i][j] << " ";
		}
		std::cout << std::endl;
	}

	std::cout << "区间遍历:" << std::endl;
	for (auto v : arr)   //v: std::array<int, 3>
	{
		for (auto vv : v) 
		{
			std::cout << vv << " ";
		}
		std::cout << std::endl;
	}
}

int main() 
{
	//operation();
	//arrayAsData();
	//OperationUserData();
	arrayNest();
	return 0;
}

STL(vector)

  • vector是动态数组,专业术语称之为向量
  • 具体函数查看vector官方手册:vector官方手册
    • assign 清除矢量并将指定的元素复制到该空矢量。
    • at 返回对矢量中指定位置的元素的引用。
    • back 返回对向量中最后一个元素的引用。
    • begin 对该向量中第一个元素返回随机访问迭代器。
    • capacity 返回在不分配更多的存储的情况下向量可以包含的元素数。
    • cbegin 返回指向向量中第一个元素的随机访问常量迭代器。
    • cend 返回一个随机访问常量迭代器,它指向刚超过矢量末尾的位置。
    • crbegin 返回一个指向反向矢量中第一个元素的常量迭代器。
    • crend 返回一个指向反向矢量末尾的常量迭代器。
    • clear 清除向量的元素。
    • data 返回指向向量中第一个元素的指针。
    • emplace 将就地构造的元素插入到指定位置的向量中。
    • emplace_back 将一个就地构造的元素添加到向量末尾。
    • empty 测试矢量容器是否为空。
    • end 返回指向矢量末尾的随机访问迭代器。
    • erase 从指定位置删除向量中的一个元素或一系列元素。
    • front 返回对向量中第一个元素的引用。
    • get_allocator 将对象返回到矢量使用的 allocator 类。
    • insert 将一个元素或多个元素插入到指定位置的向量中。
    • max_size 返回向量的最大长度。
    • pop_back 删除矢量末尾处的元素。
    • push_back 在矢量末尾处添加一个元素。
    • rbegin 返回指向反向向量中第一个元素的迭代器。
    • rend 返回一个指向反向矢量末尾的迭代器。
    • reserve 保留向量对象的最小存储长度。
    • resize 为矢量指定新的大小。
    • shrink_to_fit 放弃额外容量。
    • size 返回向量中的元素数量。
    • swap 交换两个向量的元素。
#include <iostream>
#include <vector>
void createVector()
{
	//不带长度的创建
	std::vector<int> arr;
	//不带长度不能直接使用下标法
	//错误代码
	//arr[0] = 100;
	arr.push_back(1);
	arr.push_back(2);
	arr.push_back(3);

	//带长度的创建
	std::vector<std::string> str(3);
	str[0] = "xiaogua";
	str[1] = "gua";
	str[2] = "guagua";
	//超过设置的长度,也不能使用下标法
	//错误
	//str[3] = "cool";
	//vector只有使用成员函数方式 才会具有内存自动扩增的功能

	//初始化
	//std::vector<int> num = { 1,2,3 };
	std::vector<int> num{ 1,2,3 };
}

void BasicOperation()
{
	std::vector<int> num(4);
	//前面四个元素没有赋值默认为0,在原有内存的后面插入:0 0 0 0 123
	num.push_back(123);

	//常见函数使用,大部分容器操作是一样的
	std::cout << std::endl;
	std::cout << "判断是否为空:" << num.empty() << std::endl;
	std::cout << "当前元素个数:" << num.size() << std::endl;
	//注意点: end是容器最后一个位置,不是最后一个元素的位置
	std::cout << "第一个元素:" << num.front() << " " << *num.begin() << std::endl;
	std::cout << "最后一个元素:" << num.back() << " " << *(num.end() - 1) << std::endl;
	std::cout << "获取一个元素地址:" << *num.data() << std::endl;

	std::vector<int>::iterator iter;
	for (iter = num.begin(); iter != num.end(); iter++)
	{
		std::cout << *iter << " ";
	}
	std::cout << std::endl;

}

void operationData()
{
	std::vector<int> arr{ 1,23,45,567,787 };
	std::cout << "size:" << arr.size() << std::endl;
	//删掉指定元素:
	//根据迭代器去做删除
	auto result = std::find(arr.begin(), arr.end(), 23);
	if (result != arr.end())
	{
		//删除单个元素
		arr.erase(result);
	}
	for (auto v : arr)
	{
		std::cout << v << " ";
	}
	std::cout << std::endl;
	//删除多个元素
	arr.erase(arr.begin(), arr.begin() + 3);
	for (auto v : arr)
	{
		std::cout << v << " ";
	}
	std::cout << std::endl; 
	//插入元素
	arr.insert(arr.begin(), 666);
	for (auto v : arr)
	{
		std::cout << v << " ";
	}
	std::cout << std::endl;
	arr.insert(arr.begin() + arr.size() / 2, { 1,2,3,4,5 });
	for (auto v : arr)
	{
		std::cout << v << " ";
	}
	//emplace	将就地构造的元素插入到指定位置的向量中。
	//emplace_back 将一个就地构造的元素添加到向量末尾。
	std::cout << std::endl;
	arr.emplace(arr.begin(), 1231341);
	for (auto v : arr)
	{
		std::cout << v << " ";
	}
	std::cout << std::endl;
	arr.emplace_back(111111);
	for (auto v : arr)
	{
		std::cout << v << " ";
	}
	std::cout << std::endl;
}
void testpop_back()
{
	std::vector<int> num = { 1,2,2,3,4,5,2,2,2 };
	num.pop_back();
	for (auto v : num)
	{
		std::cout << v << " ";
	}
	std::cout << std::endl;
	//删除所有相同的数据操作
	for (std::vector<int>::iterator iter = num.begin(); iter != num.end();)
	{
		if (*iter == 2)
		{
			//删除完返回的是删除元素的下一个位置
			iter = num.erase(iter);
		}
		else
		{
			iter++;
		}
	}
	for (auto v : num)
	{
		std::cout << v << " ";
	}
	std::cout << std::endl;
}
class MM
{
public:
	MM(std::string name, int age) :m_name(name), m_age(age)
	{

	}
	void printMM()
	{
		std::cout << m_name << "\t" << m_age << std::endl;
	}
	bool operator==(const std::string& str)
	{
		return this->m_name == str;
	}
	bool operator==(const int& age)
	{
		return this->m_age == age;
	}

	~MM()
	{
		//std::cout << "成功析构" << std::endl;
	}
protected:
	std::string m_name;
	int m_age;
};

//vector操作自定义类型
void operationUserData()
{
	//1.容器尽量存对象,如果存对象指针进去,需要手动释放,后续可以存智能指针对象
	std::vector<MM*> mm;
	mm.push_back(new MM("小芳", 18));
	mm.push_back(new MM("小丽", 28));
	for (int i = 0; i < mm.size(); i++)
	{
		delete mm[i];
	}
	mm.clear();
	std::vector<MM> mmObject;
	mmObject.push_back(MM("小芳", 18));
	mmObject.push_back(MM("小丽", 28));
	for (auto v : mmObject)
	{
		v.printMM();
	}
}
//简单管理系统
class student
{
public:
	student() {}
	void insertData(const MM& object)
	{
		info.push_back(object);
	}
	void printInfo()
	{
		std::cout << "姓名\t" << "年龄" << std::endl;
		for (auto v : info)
		{
			v.printMM();
		}
	}
	void eraseData(const std::string& name)
	{
		auto result = find(info.begin(), info.end(), name);
		if (result == info.end())
		{
			std::cout << "未找到指定数据无法删除" << std::endl;
		}
		else
		{
			//std::cout << "姓名\t" << "年龄" << std::endl;
			//(*result).printMM();
			info.erase(result);
			std::cout << "删除功能" << std::endl;
		}
	}
	void eraseData(const int& age)
	{
		auto result = find(info.begin(), info.end(), age);
		if (result == info.end())
		{
			std::cout << "未找到指定数据无法删除" << std::endl;
		}
		else
		{
			//std::cout << "姓名\t" << "年龄" << std::endl;
			//(*result).printMM();
			info.erase(result);
			std::cout << "删除功能" << std::endl;
		}
	}

protected:
	std::vector<MM> info;
};
void testSystem()
{
	student mm;
	mm.insertData(MM("小可爱", 18));
	mm.insertData(MM("小baby", 28));
	mm.insertData(MM("小花花", 38));
	mm.printInfo();
	mm.eraseData("小baby");
	mm.printInfo();
	mm.eraseData(38);
	mm.printInfo();
}
int main()
{
	//BasicOperation();
	//operationData();
	//testpop_back();
	//operationUserData();
	testSystem();
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值