【C++实验4】StL 应用

前言:

简单介绍:C++ STL(标准模板库)是一套功能强大的 C++ 模板类,提供了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如向量、链表、队列、栈等。

STL的一个重要特点就是数据结构和算法的分离。例如,STL中sort()函数是完全通用的,你可以用它来操作几乎任何数据集合,包括链表,容器和数组。

STL另一个重要特性是它不是面向对象的,主要依赖于模版,而不是封装和继承。

1.迭代器

STL中的迭代器是C++指针的泛化,它在算法和容器之间充当一个中间层,为处理不同的数据结构提供了一致的方式。迭代器也可以看作是对容器数据结构访问的一种约束。STL中的迭代器可分为类:随机存取迭代器(random-access-iterator),双向存取迭代器(bidirectional-access-iterator),前向迭代器(forward iterator),输入迭代器(input-iterator),输出迭代器(output-iterator)。
3.1. 输入迭代器
输入迭代器也可以称之为前向的只读访问器,首先它提供了对容器的只读访问,其次它只能在容器中进行前向迭代(即只提供++操作)。所有的容器的迭代器都具有输入迭代器的特征。通过输入迭代器你可以进行下面三种操作:
1.         V = *X++
2.         V = *X,X++
3.         V = *X,++X
注:V为值,X为迭代器
3.2. 输出迭代器
输出迭代器也可以称之为前向的只写访问器,首先它提供了对容器的只写访问,其次它只能在容器中进行前向迭代(即只提供++操作)。通过输出迭代器你可以进行下面三种操作:
1.         *X++ = V
2.         *X = V, X++
3.         *X = V, ++X
注:V为值,X为迭代器
3.3. 前向迭代器
前向迭代器继承自输入和输出迭代器,因此具有输入和输出迭代器的所有特征,也即提供对容器数据结构的读写访问但也只具有前向迭代的能力(即只提供++操作)。因此,你可以对前向迭代器进行操作:R == S /++R == ++S。
请看下面的例子:
定义一个利用前向迭代器进行线性查找的算法
template<typename ForwardIterator,typename T>
ForwardIterator linear_search(ForwardIterator first,ForwardIterator last,const T& value)
{
         for (; first != last; ++first){
                   if (*first == value)
                            return first;
}
return last;
}
测试
int ia[] = {35,3,23};
vector<int> vec(ia,ia+3);
vector<int>::iterator it = linear_search(vec.begin(),vec.end(),100);
if (it != vec.end())
std::cout << "Found" << endl;
else
std::cout << "Not Found" << endl;
          测试结果为:Not Found
3.4. 双向存取迭代器
双向存取迭代器从前向迭代器继承过来,因而具有前向迭代器的所有特征,双向存取迭代器还具有后向访问能力(即只提供--操作)。请看下面的例子:
定义一个利用双向迭代器排序算法
template<typename BidirectionalIterator,typename Compare>
void sort_me(BidirectionalIterator first,BidirectionalIterator last,Compare comp)
{
    for(BidirectionalIterator i = first; i != last; ++i)
    {
        BidirectionalIterator _last = last;
        while(i != _last--)
        {
            if (comp(*i,*_last))
                iter_swap(i,_last);
        }
    }
}
测试
int ia[] = {123,343,12,100,343,5,5};
vector<int> vec(ia,ia+7);
sort_me(vec.begin(),vec.end(),less<int>());
copy(vec.begin(),vec.end(),ostream_iterator<int>(cout," "));
std::cout << endl;
         测试结果为:5 5 12 100 123 343 343
3.5. 随机存取迭代器
随机存取迭代器从双向存取迭代器继承过来,因而具有双向存取迭代器的所有特征。所不同的是,利用随机存取迭代器你可以对容器数据结构进行随机访问,因而随机存取迭代器还可以定义下面的操作:
     operator+(int)
     operator+=(int)
     operator-(int)
     operator-=(int)
     operator[](int)
     operator-(random-access-iterator)
     operator>(random-access-iterator)
     operator<(random-access-iterator)
     operator>=(random-access-iterator)
     operator<=(random-access-iterator)
在STL中,随机存取双向迭代器只能作用于顺序容器。请看下面的例子:
         测试输出vector 里面的数据
    int ia[] = {123,343,12,100,343,5,5};
    vector<int> vec(ia,ia+7);
    for(int i = 0; i < vec.size(); ++i)
        std::cout << vec[i] << " ";
                   测试结果为:123 343 12 100 343 5 5

2.容器

容器即物之所在。容器是STL的核心部件之一,是迭代器的依附,是算法作用的目标。
STL中的容器可分为顺序容器(Sequence Container)和关联容器(Associative Container)。容器适配器(Container Adaptor)是对顺序容器(Sequence Container)或关联容器(Associative Container)进行包装而得到的一种具有更多约束力(或功能更强大)的容器。
下表列出的是STL中的主要(标准和非标准的)容器:

 

2.1关联容器

关联容器(Associative Container)提供了根据key快速检索数据的能力。在关联容器(Associative Container)中,key和元素都是成对(pair)存在的,你可以调用std::make_pair使用key和元素值来构建一个pair。
STL提供的关联容器包括set、multiset、map、multimap。
set和map只支持唯一键(unique key),即对个key最多只保存一个元素。multiset和multimap则支持多个key,一个key可以对应多个元素。
set和map的区别在于,在set里面key和元素是同一个值,而在map里面key和元素分开存储

2.1.1 Set

set是集合的抽象数据结构(ADT)。不同于数学意义上的集合,STL中的set的所有的元素都是有序的而且set中所有的元素都是唯一的。
set中的迭代器的种类为双向存取迭代器(bidirectional-access-iterator)。
请看下面的例子:
构建一个set
set<string> fruits;
往set 中添加数据
fruits.insert("apple");
fruits.insert("orange");
fruits.insert("banana");
输出set
set<string>::iterator itEnd = fruits.end();
for (set<string>::iterator it=fruits.begin(); it != itEnd; it++)
cout << *it << " ";
输出结果
         apple banana orange

2.1.2 map

map是字典的抽象数据结构(ADT)。map中的所有的元素都会根据key自动进行排序,而且所有的元素都是唯一的。map中的所有的元素都是pair,即键(key)和值(value)组成的序列(pair中的第一个元素为key,第二个元素为value)。
map中的迭代器的种类为双向存取迭代器(bidirectional-access-iterator)。
请看下面的例子:
构建一个map
typedef std::map<int,string> EMPLOYEE_MAP;
EMPLOYEE_MAP employees;
往map 中添加数据
employees.insert(EMPLOYEE_MAP::value_type(25301, "A"));
employees.insert(EMPLOYEE_MAP::value_type(25302, "B"));
employees.insert(EMPLOYEE_MAP::value_type(25303, "C"));
employees.insert(EMPLOYEE_MAP::value_type(25304, "D"));
employees.insert(EMPLOYEE_MAP::value_type(25305, "E"));
输出map
EMPLOYEE_MAP::iterator itEnd = employees.end();
for (EMPLOYEE_MAP::iterator it = employees.begin(); it != itEnd; ++it)
{
std::cout << it->first << "-";
         std::cout << it->second << endl;
}
输出结果
         25301-A
25302-B
25303-C
25304-D
25305-E
 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值