Boost中几种有趣容器的应用

目录

双射容器bimap

基本概念

bimap的使用代码举例

项目优化中bimap实战

多维数组

基本概念

multi_array使用代码举例

环形缓冲区

基本概念

circular_buffer的使用代码举例


双射容器bimap

基本概念

        C++的STL的map和mutil_map可以把key映射到value,但是这种映射关系是单向的,然而实际项目中有一些场景,双射容器更合适。boost.bimap扩展了标准库的映射容器,提高了双向映射能力,且其设计符合STL规范。

bimap的使用代码举例

#include<boost/bimap.hpp>
void  BoostTest::test_boost_bimap()
{
	using boost::bimap;
	using namespace std;
	bimap<int, string> bi;
	//实际是两个map组装 left和right 要求key-value均唯一
	bi.insert({ 2, "dog" });
	//左视图 key int
	bi.left.insert({ 1, "cat" });
	//右视图 key string
	bi.right.insert({ "pig", 3 });
	bi.right.insert(std::make_pair("bird", 4));

	for (auto &node : bi.left)
	{
		std::cout << node.first << " " << node.second << std::endl;
	}
	for (auto &node : bi.right)
	{
		std::cout << node.first << " " << node.second << std::endl;
	}
	//查找
	auto  it = bi.left.find(2); //左视图的key为整形
	if (it != bi.left.end())
		cout << it->first << "~" << it->second << endl;

	//左右视图双射容器查询
	cout << bi.left.at(2) << endl;
	cout << bi.right.at("dog") << endl;

	auto it2 = bi.right.find("dog"); //右视图的key为字符串
	if (it2 != bi.right.end())
		cout << it2->first << "~" << it2->second << endl;
}

 

项目优化中bimap实战

boost::bimap<HIK_VEHICLE_COLOR, QString> m_bimapVehicleColor;

//...
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_OTHER, "unknown"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_WHITE, "white"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_SILVER, "silver"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_GRAY, "gray"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_BLACK, "black"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_RED, "red"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_NAVY_BLUE, "deepBlue"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_BLUE, "blue"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_YELLOW, "yellow"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_GREEN, "green"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_BROWN, "brown"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_PINK, "pink"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_PURPLE, "purple"));

//...

	
//第三方接口接收字段映射为枚举值
tmp = param["vehicleColor"].toString();
if (m_bimapVehicleColor.right.count(tmp) > 0)
{
	vehicle.VehicleColor = (int)m_bimapVehicleColor.right.at(tmp);
}

//...
//对内枚举值映射为对外描述字符串
QString vehicleColorStr = m_bimapVehicleColor.left.at(ISC_VEHICLE_COLOR_WHITE);
	

多维数组

基本概念

        multi_array它实现了一个通用、与标准库的容器一致的接口,并且具有与C++中内建的多维数组一样的界面和行为。正是基于这种通用性的设计,MultiArray库与标准库组件甚至用户自定义的泛型组件之间可以具有很好的兼容性,并能够很好的协同工作。

        除此之外,MultiArray还提供了诸如改变大小、重塑(reshaping)以及对多维数组的视图访问等极为有用的特性,从而使MultiArray比其它描述多维数组的方式(譬如:std::vector< std::vector<...> > )更为便捷、高效。

multi_array使用代码举例

#include"boost/multi_array.hpp"
#include<boost/array.hpp>

void BoostTest::test_boost_mutil_array()
{
	//运行时多维数组 c++的数组必须指定二维以上维度 int a[n][10][3]
	using boost::multi_array;
	int a = 2, b = 3, c = 4;//可以cin>>输入
	//通过boost::extents函数创建多位数组
	multi_array<int, 3>arr(boost::extents[a][b][c]);
	
	//通过一纬固定大小数组值创建多维的纬度 2页3行4列
	boost::array<int, 3>wd2 = {2,3,4};
	multi_array<int, 3>arr2(wd2);
	
	
	//打印数组的每一个维度
	std::cout << "维度:" << arr2.num_dimensions() << ","
		<< arr2.shape()[0] << "," //2
		<< arr2.shape()[1] << "," //3
		<< arr2.shape()[2]<<","   //4
		<< "元素个数" << arr2.num_elements()<<std::endl;

	for (int i = 0; i < arr2.shape()[0]; i++)
	{
		for (int j = 0; j < arr2.shape()[1]; j++)
		{
			for (int k = 0; k < arr2.shape()[2]; k++)
			{
				arr2[i][j][k] = i * 100 + j * 10 + k;
			}
		}
	}
	
	//遍历 类似图书管理 x图书室 y图区 z图书架 m层 n本 i页 j行 k列
	for (int i = 0; i < arr2.shape()[0]; i++)
	{
		std::cout << i << "页" << std::endl;
		for (int j = 0; j < arr2.shape()[1]; j++)
		{  
			for (int k = 0; k < arr2.shape()[2]; k++)
			{
				std::cout << i << "页" << j << "行" << k << "列" << arr2[i][j][k]<<" ";
			}
			std::cout << std::endl;
		}
	}

	//改变数组维度 原有的元素将被复制到新内存
	arr2.resize(boost::extents[4][5][6]);
	arr2[3][4][5] = 99;
	std::cout << arr2[0][0][0] << arr2[0][1][0] << arr2[3][4][5] << std::endl;
	
	boost::array<int, 3>wd = { 2, 5, 12 };//4*5*6 = 2*5*12
	arr2.reshape(wd);
	//遍历
	for (int i = 0; i < arr2.shape()[0]; i++)
	{
		std::cout << i << "页" << std::endl;
		for (int j = 0; j < arr2.shape()[1]; j++)
		{
			for (int k = 0; k < arr2.shape()[2]; k++)
			{
				std::cout << i << "页" << j << "行" << k << "列" << arr2[i][j][k] << " ";
			}
			std::cout << std::endl;
		}
	}
}

 

环形缓冲区

基本概念

  boost库中的 circular_buffer顾名思义是一个循环缓冲器,其 capcity是固定的当容量满了以后,插入一个元素时,会在容器的开头或结尾处删除一个元素。如图所示:

 

  添加元素:push_back()、push_front()、insert()。

  删除元素:pop_back()、pop_front()、erase()。

  判断容器是否已满:full()。

  把缓冲区线性化一个连续的普通数组:linearize()。

  来检测是否可以线性化:is_linearize()。

  从指定的迭代器位置旋转整个容器:rotate()。 

        需要注意的是circular_buffer的迭代器不是循环的,指向或超过end()的迭代器也会引发断言异常,前面所说的到达末尾时自动循环使用容器的另一端空间指的是当达到容器的容量上限,继续push_back方法压入元素时,原来begin处的元素就会被覆盖,原来begin + 1处的元素成为新的begin。如果我们需要一种容器在达到容量上限的情况下自动覆盖前面的数据的话就可以使用circular_buffer,整体上来说是一种FIFO的缓存。

circular_buffer的使用代码举例

#include<boost/circular_buffer.hpp>
void BoostTest::test_boost_circular_buffer()
{
	//环形缓存(特别像队列)
	boost::circular_buffer<int>  cb(5);//容量为3

	cb.push_back(1);//从尾部插入
	cb.push_back(2);
	cb.push_back(3);
	cb.push_back(4);
	cb.push_back(5);//容量已满 1 2 3 4 5


	for (int i = 0; i < cb.size(); ++i)
	{
		cb[i] = cb[i] + 1;//修改缓存内容
		std::cout << cb[i] << "   ";	// 2 3 4 5 6
	}
	std::cout << std::endl;


	//容量已满,尾部插入,踢出头部元素
	cb.push_back(7);
	for (int i = 0; i < cb.size(); ++i)
	{
		std::cout << cb[i] << "   ";//3 4 5 6 7
	}
	std::cout << std::endl;

	//容量已满,头部插入,踢出尾部元素
	cb.push_front(1);
	for (int i = 0; i < cb.size(); ++i)
	{
		std::cout << cb[i] << "   ";
	}
	std::cout << std::endl;//1 3 4 5 6

	cb.pop_back();//删除尾部的元素
	for (int i = 0; i < cb.size(); ++i)
	{
		std::cout << cb[i] << "   ";	
	};
	std::cout << std::endl;// 1 3 4 5

	cb.pop_front();//删除头部的元素
	for (int i = 0; i < cb.size(); ++i)
	{
		std::cout << cb[i] << "   ";
	}
	std::cout << std::endl;//3 4 5
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值