C++大法:举世闻名之BOOST大法精华浅析(六)容器与数据结构

六、容器与数据结构

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 ;
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白piao

创作不易,支持一下!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值