六、容器与数据结构
6.1 array
封装了C++标准库中的数组,为其提供了标准的STL容器接口,在对性能要求很高且不要求动态扩容的情况下使用。
其中并不能作为参数传入C语言当中的有些常见的接口(例如some_func(void* n,int len))
本库已经收录如c++新标准的TR1库中
-
简单例子:
#include <iostream> #include <boost/array.hpp> #include <boost/assign.hpp> using namespace std; //using namespace boost; using namespace boost::assign; bool compare(int a, int b){ return a>b; } int main() { //array:静态数组 ,长度固定,和int arr[len]相同。 //array<int,10> ar={0};//或者: boost::array<int,10> ar=(list_of(1)(2),3,5); //fill_n(ar,10,0); //遍历: for (auto it=ar.begin();it!=ar.end();it++) { cout<<*it<<endl; } cout<<ar.front()<<endl;//第一个 元素 cout<<ar.back()<<endl;//最后一个 元素 ar.assign(100);//数组的所有元素赋值为100 ar[1] = 3; cout<<ar.at(1)<<endl;//得到下标所对应的值 int* p = ar.c_array();//得到内部封装的数组 p[0] = 1; //c数组的下标遍历: // for (unsigned i=0;i<ar.size();i++) { // cout<<p[i]<<endl; // } sort(ar.begin(),ar.end(),compare);//采用常规算法排序 cout<<"------------sorted---------------"<<endl; for (unsigned i=0;i<ar.size();i++) { cout<<p[i]<<endl; } cout<<"done"<<endl; return 0; }
-
注意:
- array的功能非常局限,虽然看着像是一个模板,但是实际上并不是,其没有构造函数,不能动态扩容
- 只对某些场合对速度要求很高时才会用到
- 如果对效率要求不是很高,建议使用std::vector 或者 boost::scoped_array
6.2 dynamic_bitset
既能够支持位运算,又能够支持扩容的二进制处理工具。
6.3 unordered
散列容器(hash_container)是一种非常重要的容器类型。他通常比二叉树的存储方式可以提供更高的访问效率。C++98中并未定义散列容器,编译器厂商实现了名如hash_map和hash_set的散列容器。
C++标准委员会有了时间,开始整理散列容器的标准时,将名称改为unordered_xxx,更好的体现了其本质-----无序的。因为散列容器的无序性,因此不需要容器的元素类型提供operator<,而是使用散列函数和键值比较的operator==。
boost.unordered库中提供了一个完全符合C++新标准草案的散列容器实现,包括无序集合和无序映射。位于boost命名空间中,为使用unordered库,需要包含头文件<boost/unordered_set.hpp>或者<boost/unordered_map.hpp>即:
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
using namespace boost;
6.3.1 散列集合
unoredered_set 和 unordered_multiset ,他们的接口、用法和STL中的set、multiset一样,只是用hash表替代了二叉树。
-
简单例子:
#include <iostream> #include <boost/unordered_map.hpp> #include <boost/unordered_set.hpp> using namespace std; using namespace boost; template <class T> void hash_func() { using namespace boost::assign; T s = (list_of(1),2,3,4,5); for (typename T::iterator it = s.begin();it!=s.end();it++) { cout<<*it<<endl; } cout<<"-----size------"<<endl; cout<<s.size()<<endl; cout<<"-----clear-----"<<endl; s.clear(); cout<<s.empty()<<endl;//1 s.insert(10); s.insert(45); cout<<"-----size------"<<endl; cout<<s.size()<<endl; //2 cout<<"-----find------"<<endl; cout<<*s.find(8)<<endl; //未找到,不报错,打印空 s.erase(45); } int main() { hash_func<unordered_set<int> >(); return 0; }
-
关于set、hash_set、unordered_set的性能直观分析
template <typename T> void test_eff() { T t; cout<<typeid(t).name()<<endl; { ptimer pt; fill_set(t); } { ptimer pt; t.count(10); } { ptimer pt; t.find(20); } } int main() { //3、性能测试: test_eff<set<int> >(); test_eff<unordered_set<int> >(); return 0; }
6.3.2 散列映射
属于关联容器,使用和标准库map一模一样,只是内部用散列替换了树的实现而已。同样采用std::pair 保存一个key-value的数据,提供[]重载。unordered_map允许重复的键值对,所以没有[]重载运算符。
#include <iostream>
#include <boost/assign.hpp>
#include <boost/unordered_map.hpp>
using namespace std;
using namespace boost;
int main()
{
using namespace boost::assign;
unordered_map<int,string> um = map_list_of(1,"hello")(2,"python");
um.insert(make_pair(3,"c++"));
cout<<um[3]<<endl;
um[11] = "eleven";
um[15] = "fifteen";
auto it = um.begin();
for (;it!=um.end();it++) {
cout<<it->first<<"---"<<it->second<<endl;
}
cout<<um.size()<<endl;
um.erase(12);
um.erase(11);
cout<<um.size()<<endl;
return 0;
}
6.4 tuple
tuple(元组)是一种由固定元素数目的容器,其中每个元素都可以是不同的数据类型。其作用非常重要,可以从函数返回任意数量的值,也可以代替struct组合数据。
tuple位于命名空间boost::tuples中,但是大部分功能被using语句引入了boost命名空间中,为了使用tuple组件,需要包含头文件<boost/tuple/tuple.hpp>,即:
#include<boost/tuple/tuple.hpp>
using namespace boost;
-
类摘要:
#include <iostream> #include <boost/tuple/tuple.hpp> #include <string> using namespace boost; int main() { //4、tuple元组: using std::cout, std::endl, std::string ; boost::tuple<int,string> mytp(1,"a"); cout<<mytp.get<1>()<<endl;// a tuple<int, string> mytp1(mytp); cout<<mytp1.get<0>()<<endl; tuple<int, string> mytp2=mytp; cout<<mytp2.get<0>()<<endl; tuple<int, string> mytp3=make_tuple(1,"hello"); cout<<mytp3.get<1>()<<endl; mytp3.get<0>() = 3;//其中的值可以修改 cout<<mytp3.get<0>()<<endl; //简化用法: auto tp = make_tuple(1,2.32,"hello"); cout << get<0>(tp)<<endl;// 1 //这是另外一种get方法 return 0 ; }
-
连接变量:tie()函数
#include <iostream> #include <boost/tuple/tuple.hpp> #include <string> using namespace boost; boost::tuple<int, std::string> retTuple() { return make_tuple(1,"hello"); } int main() { int i; string str; tie(i,str) = retTuple(); cout<<i << "------" <<str<<endl; tie(boost::tuple::ignore, str) = retTuple();//忽略第一个参数 cout<<str<<endl; return 0 ; }