Thinking in C++第二卷笔记之STL容器部分(三)

Thinking in C++第二卷笔记之STL容器部分(三)

相关日志

STL的总结

http://blog.163.com/zhoumhan_0351/blog/static/3995422720103174417603

标准模板类(STL)(四),容器的比较、对比和总结

http://blog.163.com/zhoumhan_0351/blog/static/3995422720102267442299

标准模板类(STL)(五),算法和函数

http://blog.163.com/zhoumhan_0351/blog/static/39954227201022783524890

Thinking in C++第二卷笔记之STL容器部分(二)

http://blog.163.com/zhoumhan_0351/blog/static/399542272010457193722/

priority_queue优先队列容器

http://blog.163.com/zhoumhan_0351/blog/static/3995422720103510163429

1、优先队列

可以说堆就是一个优先队列,priority_queue只是对它的一个封装。

2、vector<bool>和bitset

     来操作硬件。bitset模板为了操作二进制位设计,不是一个正常的STL容器,没有迭代器,拥有一个面向二进制位层次的操作接口。而vector<bool>是vector的一个特化,有普通vector的所有操作。

bitset接受一个无符号整形模型参数。bitset<10>,bitset<20>是两种不同的类型,不能相比较,赋值等操作。each bitset is implemented by logically packing bits 

in an array of integral types (typically unsigned longs, which contain at least 32 bits). 

In addition, the only conversion from a bitset to a numerical value is to an unsigned 

long (via the function to_ulong( )).

Although there are no other numerical conversions from bitset besides 

to_ulong( ), there is a stream inserterthat produces a string containing ones and 

zeros, and this can be as long as the actual bitset.

You’ll notice that bitset only has three nonmember operators: and (&), or (|), 

and exclusive-or (^). Each of these creates a new bitset as its return value. All the 

member operators opt for the more efficient &=, |=, and so on, where a temporary is 

not created. However, these forms change the bitset’s value。所以我们通常要写成BS(a)的形式,如cout << (BS(a) <<= SZ/2)。

The vector<bool> container is a specialization of the vector template. A normal 

bool variable requires at least one byte, but since a bool only has two states, the 

ideal implementation of vector<bool> is such that each bool value only requires one 

bit. Since typical library implementations pack the bits into integral arrays, the iterator 

must be specially defined and cannot be a pointer to bool.The bit-manipulation 

functions for vector<bool> are much more limited than those of bitset. The only 

member function that was added to those already in vector is flip( ), to invert all the 

bits. There is no set( ) or reset( ) as in bitset. When you use operator[], you get back 

an object of type vector<bool>::reference, which also has a flip( ) to invert that 

individual bit.

#include <bitset>

#include <iostream>

#include <iterator>

#include <sstream>

#include <vector>

using namespace std;

int main() {

  vector<bool> vb(10, true);

  vector<bool>::iterator it;

  for(it = vb.begin(); it != vb.end(); it++)

    cout << *it;

  cout << endl;

  vb.push_back(false);

  ostream_iterator<bool> out(cout, "");

  copy(vb.begin(), vb.end(), out);

  cout << endl;

  vb.flip(); // Flip all bits

  copy(vb.begin(), vb.end(), out);

  ostringstream os;

  copy(vb.begin(),vb.end(),ostream_iterator<bool>(os, ""));

  bitset<10> bs(os.str());

  cout << "Bitset:"<< endl << bs << endl;

}

// Let c be an STL container other than vector<bool>:

常规容器都有的操作,如下:

T& r = c.front();

T* p = &*c.begin();

但是由于二进制位是不可寻址的,所以上面的两个函数不可能用于处理持有二进制位的容器。Both vector<bool> and bitset use a proxy class (the nested 

reference class to read and set bits as necessary.

3、对于一个map,在数组范围以外的位置进行索引意味着创建新条目。

pair由值封装它的对象,这意味着对象装入pair之内,拷贝构造是必须的。对于每个pair中的对象包括至少一个拷贝函数调用和一个析构函数调用。使用迭代器不会产生额外的对象的析构和构造操作。

如下是一个单词计数器

// Count occurrences of words using a map.

#include <iostream>

#include <fstream>

#include <map>

#include <string>

using namespace std;

int main() {

  typedef map<string, int> WordMap;

  typedef WordMap::iterator WMIter;

  //const char* fname = "C:\\bsmain_runtime.txt";

  ifstream in("C:\\bsmain_runtime.log");

  if(NULL==in) {

   cout<<"Failed";

      return 1;

  }

  WordMap wordmap;

  string word;

  while(in >> word)

    wordmap[word]++;

  for(WMIter w = wordmap.begin(); w != wordmap.end(); w++)

    cout << w->first << ": " << w->second << endl;

} ///:~

下面是另外一个有趣的例子:

  string reply;

  cin>>reply;

  if(reply.at(0)=='q') return 0;

  istringstream r(reply);

  int i;

  r>>i;

我们用multiset来做上面的那个例子,更优雅的实现。

#include <fstream>

#include <iostream>

#include <iterator>

#include <set>

#include <string>

using namespace std;

int main() {

  const char* fname = "C:\\bsmain_runtime.log";

  ifstream in(fname);

  multiset<string> wordmset;

  string word;

  while(in >> word)

    wordmset.insert(word);

  typedef multiset<string>::iterator MSit;

  MSit it = wordmset.begin();

  while(it != wordmset.end()) {

    pair<MSit, MSit> p = wordmset.equal_range(*it);

    int count = distance(p.first, p.second);//对该范围内的元素进行计数

    cout << *it << ": " << count << endl;

    it = p.second; // Move to the next word

  }

} ///:~

template<class Init, class Dist>

    ptrdiff_t distance(InIt first, InIt last);

The template function sets a count n to zero. It then effectively advances 

first and increments n until first == last. If InIt is a random-access iterator 

type, the function evaluates the expression n += last - first. Otherwise, it 

performs each iterator increment by evaluating ++first.

multiset要求所有重复的元素必须相互比邻的存放。一个set实现可能使用散列函数进行排列元素。

    在编译器实例化时,所需要的ostream_iterator特化根据参数关联查找(ADL)规则,只查找std。

    在删除一个指针后将其值置为零,对一个零指针调用删除操作delete是一个安全的操作。

4、对STL的扩充

    利用散列算法实现的set和map比树型数据结构有更高的效率。在SGI中有提供,如hash_multiset,hash_map,hash_multimap,slist,和rope(它是一个string的变种,对非常大型的字符串,字符串的快速连接和取子串等操作进行了优化)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值