STL—其它容器


  在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++ array
	vector<int> vec;//STL vector

	//initialize each element of they array to the value of its index
	for(int i = 0; i < 10; i++)
	{
		arr[i] = i;
	}

	//insert the contents of the array into the end of the vector
	vec.insert(vec.end(), arr, arr+10);

	//print the contents of the vector
	for(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 vector
	copy(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;
}


  输出结果:



  没了。




原文地址:https://www.cnblogs.com/javawebsoa/p/3113009.html