STL—其它容器

来源:互联网 发布:微信业务域名是什么 编辑:程序博客网 时间:2024/05/18 03:18


  在C++语言中,有一些诸如数组、string、流和 bitset 虽然说并非属于标准STL,但在某种程度上与 STL 相关。以下就简单介绍一下。

  数组作为STL容器

  我们知道,“哑”指针可以很好的作为迭代器,因为它们支持所需的操作符。这一点绝非小事,这说明你可以把常规的C++数组当作 STL 容器,自学使用元素的指针作为迭代器。当然,数组并没有提供诸如 size ( ) 、empty ( ) 、insert ( ) 和 erase ( ) 等方法,因此它们不是真正意义上的容器。不过,数组通过指针确实支持迭代器,通过以下一个小例子简单看一下即可。

#include<vector>#include<iostream>using namespace std;int main(){int arr[10];//normal C++ arrayvector<int> vec;//STL vector//initialize each element of they array to the value of its indexfor(int i = 0; i < 10; i++){arr[i] = i;}//insert the contents of the array into the end of the vectorvec.insert(vec.end(), arr, arr+10);//print the contents of the vectorfor(i = 0; i < 10; i++){cout << vec[i] <<" ";}return 0;}

 tips:需要注意,指示数组第一个元素的迭代器只是第一个元素的地址。指示最后位置的迭代器必须是越过最后一个元素的位置,因此这是第一个元素的地址加 10。


  string 作为 STL 容器

  可以把 string 看作是字符的一个顺序容器。它包括 begin( ) 和 end( ) 方法(会返回指向 string 内部的迭代器)、insert( ) 和 erase( ) 方法、size( ) 、empty( ),以及所有其他顺序容器的基本功能。这与 vector 相当接近,甚至还提供了 reserve( ) 和 capacity( ) 方法。不过,不同于 vector ,string 不需要将元素连续地存储在内存中。另外 vector 提供的某些方法 string 并没有提供,如 push_back( )。例如:

#include<string>#include<iostream>using namespace std;int main(){string str;str.insert(str.end(),'h');str.insert(str.end(),'e');str.insert(str.end(),'l');str.insert(str.end(),'l');str.insert(str.end(),'0');for(string::const_iterator it = str.begin(); it !=str.end(); it++){cout << *it;}cout << endl;return 0;}

 

  流作为 STL 容器

  从传统意义上讲,输入和输出流并不是容器,它们不存储元素。不过,可以把流考虑成元素序列,因此与 STL 容器有一些共同的特性。 C++ 流没有直接提供任何与STL相关的方法,但是 STL 提供了一些特殊的迭代器,名为 istream_iterator 和 outstream_iterator ,由此可以“迭代”处理输入和输出流。使用这些迭代器,就可以对输入和输出流进行适配,这样输入和输出流就可以在各种STL算法中分别用作源和目标。例如,可以使用 ostream_iterator 利用 copy ( ) 算法打印出一个容器中的元素,这只需一行代码:

#include<algorithm>#include<iostream>#include<iterator>#include<vector>using namespace std;int main(){vector<int> myVector;for(int i= 0; i < 10; i++)myVector.push_back(i);//print the contents of the vectorcopy(myVector.begin(), myVector.end(), ostream_iterator<int>(cout, " "));cout<<endl;return 0;}

  ostream_iterator 是一个模板类,它取元素作为一个类型参数。其构造函数取一个输出流和一个 string 作为参数,该 string 是在各元素之后写至流的字符串。(由于这里 string 参数为“”,其作用是在输出的各元素之间用空格分隔开)。

  类似地,可以使用迭代器抽象利用 istream_iterator 从一个输入流读取值。istream_iterator 可以在算法和容器方法中用作源。它不如 ostream_iterator 那么常用,所有在这里就不再提供输入流迭代器的例子。


  bitset

  bitset 是位序列的一个定长抽象。一位表示两个值,通常表示为 1 和 0 、开和关、true 和 false 。bitset 也使用术语设置(set)和反设置(unset)。可以对一位触发(toggle)或取反(flip),使之从一个值变为另一个值。

  bitset 并不是真正的STL容器,它是定长的,并非对元素类型模板化,而且不支持迭代。不过,这是一个很有用的工具,经常与容器一起使用,所以有必要了解一下 bitset 。

  bitset 基本知识

  bitset 在 <bitset> 头文件中定义,它基于所存储的位数来实现模板化。默认构造函数会把 bitset 的所有位域初始化为 0.另外一个构造函数可以从一个由 0 和 1 组成的 string 创建 bitset 。

  可以用 set( )、reset( ) 和 flip( ) 方法调整单个位的值,可以用一个重载的 operator[ ] 访问和设置 bitset 的位域。需要注意,在一个非 const 对象上调用 operator [ ] 会返回一个代理对象,可以对其赋一个布尔值、调用 flip( ) ,或者用 ~ 取反。还可以用 test( ) 方法访问单个的位域。

  另外,可以用常规的流插入和析取操作符完成 bitset 的流输入和输出。bitset 会作为包括 0 和 1 的字符串流入流出。

  以下是一个小例子。

  

#include<bitset>#include<iostream>using namespace std;int main(){bitset<10> myBitset;myBitset.set(3);myBitset.set(6);myBitset[8] = true;myBitset[9] = myBitset[3];if(myBitset.test(3)){cout<<"Bit 3 is set!"<<endl;}cout << myBitset <<endl;return 0;}

  输出为:

  

  tips:输出 string 中最左字符是最高编号位(即编号或索引为 9)。


  位操作符

  除了基本位处理例程,bitset 还提供了所有为操作符的实现:&、|、^、~、<<、>>、&=、|=、^=、<<= 和 >>=。这些操作符表现得就好像在“真的”位序列上操作一样。以下是一个例子。

#include<bitset>#include<iostream>using namespace std;int main(){string str1 = "0011001100";string str2 = "0000111100";bitset<10> bitsOne(str1),bitsTwo(str2);bitset<10> bitsThree = bitsOne & bitsTwo;cout << bitsThree <<endl;bitsThree <<= 4;cout << bitsThree << endl;return 0;}

  输出结果:



  没了。




原创粉丝点击