设为首页 加入收藏

TOP

《C++ Primer Plus》学习笔记10(二)
2015-07-20 18:04:27 来源: 作者: 【 】 浏览:7
Tags:Primer Plus 学习 笔记

迭代器,要为vector的double类型规范声明一个迭代器

vector
   
    ::iterator pd; vector
    
      scores;//scores是一个vector
     
      对象 pd = scores.begin();//初始地址 *pd = 22.3;//第一个元素的值 ++pd; 
     
    
   

遍历整个容器的内容:

for(pd = scores.begin(); pd != scores.end(); pd++)
    cout << *pd << endl;

push_back()是一个方便的方法,它将元素添加到矢量末尾,它负责内存管理,增加矢量的长度,使之能容纳新的成员

vector
   
    scores;//创建一个空的向量 double temp; while(cin>>temp && temp >= 0) scores.push_back(temp); cout << "You entered" << scores.size() << " scores.\n"; 
   

erase()方法删除矢量中给定区间的元素,它接受两个迭代器参数,这些参数定义了要删除的区间,第一个迭代器指向区间的起始处,第二个迭代器位于区间终止处的后一个位置

scores.erase(scores.begin(), scores.begin() + 2);//即删除了begin()和begin()+1指向的元素

记住:区间[it1, it2]由迭代器it1和it2指定,其范围为it1到it2不包括it2
insert()方法与erase()相反,它接受3个迭代器参数,第一个参数指定了新元素的插入位置,第二个和第三个参数定义了被插入区间

old.insert(old.end(),new.begin()+1,new.end());//将矢量new中除第一个元素以外的所有元素插入到old矢量的第一个元素的前面

3)对矢量可执行的其他操作
搜索、排序、随机排序
for_each()函数用于许多容器类,它接受3个参数,前两个是定义容器中区间的迭代器,最后一个是指向函数的指针,被用来指向函数应用与容器区间中的各个元素,被指向的函数不能修改容器元素的值;可以用for_each循环代替for循环

vector
   
    ::iterator pr; for(pr = books.begin();pr != books.end(); pr++) ShowReview(*pr); 
   

替换为

for_each(books.begin(),books.end(),ShowReview);//这样避免显式地使用迭代器变量

Random_shuffle()函数接受两个指定区间的迭代器参数,并且随机排列该区间中的元素

random_shuffle(books.begin(), books.end());//随机排列books矢量中的所有元素

sort()也要求容器支持随机访问

//版本一接受两个迭代器参数
vector
   
     coolstuff; …… sort(coolstuff.begin(),coolstuff.end());//升序 //版本二如果容器元素是用户定义的对象,必须定义能够处理类型对象的operator<()函数 bool operator< (const Review & r1, const Review & r2) { if(r1.title < r2.title) return true; else if(r1.title == r2.title && r1.rating < r2.rating) return true; else return false; } 
   

有了这样的函数之后,我们就可以对包含Review对象如books的矢量进行排序

sort(books.begin(), books.end());//升序排序,全排序

上述版本是按照title成员的字母顺序排序,如果title成员相同,则按照rating排序

bool WorseThan (const Review & r1, const Review & r2)
{
    if(r1.title < r2.title)
        return true;
    else
        return false;
}

有了这个函数,就可以将包含Review对象的books的矢量按rating升序排列

sort(books.begin(), books.end(), WorseThan);//升序排序,完全弱排序

4、通用编程技术
STL是一种通用编程技术,面向对象编程关注的是编程的数据方面,而通用编程技术关注的是算法,共同之处是抽象和创建可重用的代码。
通用编程技术旨在编写独立于数据类型的代码,在C++中,完成通用程序的工具是模板
1)模板使得算法独立于存储的数据类型,而迭代器使算法独立于使用的容器类型,它们都是STL通用方法的重要组成部分
2)为什么要使用迭代器?
目的是为了编写算法时,尽可能使用要求最低的迭代器,并让它适用于容器的最大区间。这样通过使用级别最低的输入迭代器,find()函数便可用于任何包含可读取值的容器,sort()函数由于需要随机访问迭代器,所以只能用于支持这种迭代器的容器。

//在一个double数组中搜索特定值的函数
double * find_ar(double * ar, int n, const double & val)
{
    for(int i = 0; i < n; i++)
        if(ar[i] == val)
            return &ar[i];
        return 0;
}

使用迭代器

typedef double * iterator;
iterator find_ar(iterator begin, iterator end, const double & val)
{
    iterator ar;
    for(ar = begin; ar != end; ar++)
        if(*ar == val)
            return ar;
        return end;
}

总结下STL方法,首先是处理容器的算法,应尽可能用通用的术语来表达算法,使之独立于数据类型和容器类型,为使通用算法能够适用于具体情况,应定义能够满足算法需求的迭代器,并把要求加到容器设计上,所以要设计基本迭代器的特征和容器特征。
3)迭代类型
①输入迭代器――被程序用来读取容器中的信息
单向迭代器,只读,只能递增,不能倒退。
②输出迭代器――将信息从程序传输给容器的迭代器,程序的输出就是容器的输入
单向迭代器,只写
③正向迭代器――使用++操作符来遍历容器,正向迭代器既可以使得能够读取和修改数据,也可以使得只能读取数据

int * pirw;//读写迭代器
const int * pir;//只能读取迭代器

④双向迭代器――具有正向迭代器所有特性,同时支持两种递减操作符
reverse函数可以交换第一个元素和最后一个元素,将指向第一个元素的指针加1、将指向第二个元素的指针减去1,并且重复这种处理过程。
⑤随机访问迭代器――具有双向迭代器所有特性,同时添加了支持随机访问的操作
X表示随机迭代器类型,T表示被指向的类型,a和b是迭代器值,n为整数,r为随机迭代器变量或引用
随机访问迭代器操作:

a+n 指向a所指向元素后的第n个元素
a-n 指向a所指向元素前的第n个元素
a[] 等价于*(a+n)

4)概念、改进和模型
概念的具体实现被称为模型
①将指针用作迭代器
迭代器是广义的指针,指针满足所有迭代器的要求,迭代器是STL算法的接口,而指针是迭代器,所有STL算法可用于常规数组。
copy()、ostream_iterator和istream_iterator
copy() 将数据从一个容器复制到另一个容器中

int casts[10] = {6, 7, 2, 9, 4, 11, 8, 7, 10, 5};
vector
   
     dice[10]; copy(casts, casts + 10, dice.begin());//前两项是复制的范围,后面是复制到什么位置 
   

使用注意事项:
前两个参数最好是输入迭代器,最后一个参数最好是输出迭代器;
copy()函数将覆盖目标容器中已有的数据,我们不能将数据放入空矢量中;
ostream_iterator
是输出迭代器概念的一个模型,它是一个适配器(adapter

首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Codeforces 448E Divisors 下一篇A POJ1611

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: