Essential c++学习笔记(3.1-3.4)

最近在看这本书入门c++把书上的代码敲了一遍,一边看书一边理解。这样的方式确实比单单看书效果好很多
由于以前写的代码我基本不会打开看,所以决定抄到博客,浏览博客似乎很方便

 //给定储存整数的vector,以及
//一个整数值,如果此整数值存在于vector内,我们必须返回一个指针指向该值。
const int arraysize=5;
int a[arraysize]={1,2,3,4,5};
vector<int> aa(a,a+arraysize);
int* find(const vector<int> &aa,int value)
{
    for(int i=0;i<aa.size();i++)
    {
        if(aa[i]==value)
            return &aa[i];
        return 0;
    }
} 
//接下来要求不仅可以处理整数还可以处理任何类别,前提是该类型有相等运算符
template<typename elemType>
elemType* find(const vector<elemType> &aa,elemType value>
{
    for(int i=0;i<aa.size();i++)

           if(aa[j]==value)
           return &aa[i];
    return 0;
}
//下一步同时可以处理vector和array的任意类型元素,
//用分割大问题为单个小问题这个方法
template<typename elemType>
elemType* find(const elemType* array,int size,elemType value)
{
    if(!array||size<1) return 0;
    for(int i=0;i<size;i++;++array)
       if(*arrry==value)
        return array;
    return 0;
}
//用第二个指针来取代参数size。此指针扮演着标兵的角色。
//这个版本中我们可以将array的声明完全移除
template<typename elemType>
elemType* find(const elemType *first,const elemType *last,elemType &value)
{
    if(!first||!last)
    for(first!=last;first++)
        if(*first==value)
            return first;
    return 0;
}
//接下来如何调用find()?,接下来用到指针算术与运算解决这个调用问题
int ia[8]={1,1,2,3,5,8,13,21};
double da[6]={1.5,2.0,2.5,3.0,3.5,4.0};
string sa[4]={"pooh","piglet","eeyore","tigger"};
int *pi=find(ia,ia+8,ia[3]);
double *pd=find(da,da+6;da[3]);
string *ps=find(sa,sa+4,sa[3]);
//对应于vector的情况。用启动地址和结束地址作为参数传入find(),vector可以为空,array不可以
//提前验证vector不为空
//将取用第一个元素的地址的操作包装为函数
template <typename elemType>
inline elemType* get_thefirst(const vector<elemType> &vec)
{
    return vec.empty ? 0:&vec[0];
}
template <typename elemType>
inline elemType* get_thelast(const vector<elemType> &vec)
{
    return vec.empty? 0:&vec[size];//此处返回的是vec最后元素的下一个地址
}
//如何让我们的程序进一步支持list容器,list是以一组指针相互链接:前向指针指向下一个元素,后向指针指向上一个元素
//在底层指针的行为之上提供抽象层,取代原本的指针直接操作,将对底层指针的处理全部放在抽象层内,让用户无法直接面对指针操作
//泛型指针,此处关注的是使用,后续的书中给出了如何写泛型
while(first!=last)
{
    cout<<*first<<' ';
    ++first
}
//区别在于提领,等于不等于,递增等运算符由iterator class内部相关的inline函数提供。这里不多探讨
//每个标准容器都会有一个名为begin()的操作函数会返回一个iterator指向第一个元素,end()会返回一个iterator指向最后一个
//元素的下一个位置
for(iter=svec.begin();iter!=svec.end();++iter)
    cout<<*iter<<' ';
vector<string> svec
    vector<string>::iterator iter=svec.begin();//此处定义了一个泛型指针,告诉我们该怎么定义一个泛型指针,需要哪些,容器类型决定指针的工作方式
//string数据类型
const vector<string> cs_vec;
vector<string>::const_iterator iter=cs_vec.begin();
//采取一般指针的提领方法来取得元素值
cout<<"string value of element:"<<*iter;
//调用底层string元素所提供的操作,使用arrow
cout<<"("<<iter->size()<<")"<<*iter<<endl;
//实现display()(应该是前面已经实现的函数重新改写)
template<typename elemType>
void display(const vector<elemType>&vec,ostream &os)
{
    vector<elemType>::const_iterator iter=vec.begin();
    vector<elemType>::const_iterator end_it=vec_end();
    for(;iter!=end_it;++iter)
        os<<*iter<<' ';
    os<<endl;
}
//重新实现前面的find(),同时支持两种形式:一对指针,或是一对指向某种容器的iterator
template<typename iteratorType typename elemType>
iteratorType find(iteratorType first,iteratorType last,elemType &value)
{
    for(;first!=last;first++)
        if(*first==value)
            return first;
    return last;
}
//使用翻修的find()来处理array,vector,list:
const int asize=8;
int ia[asize]={1,1,2,3,5,8,13,21};
vector<int> ivec(ia,ia+asize);
list<int> ilist(ia,ia+asize);
int *pia=find(ia,ia+asize,1024);
if(pia!=ia+asize)
    //找到了
vector<int>::iterator it;
it=find(ivec.begin(),ivec.end(),1024);
if(it!=ivec.end)
    //找到了
list<int>::iterator iter;
iter=find(ilist.begin(),ilist.end(),1024);
if(iter!=ilist.end())
    //找到了
//以上find()使用了底部元素所属类型的等号,如果底部元素所属类型没有提供此号。或者=意义不同find()的弹性就不同
//传入函数指针增加弹性取代=号
//======================================================//
//vector比较适合表示数列,因为随机访问,并且加以索引,且只需要在末尾添加删除效率比较高
//list任意位置添加删除都效率还ok,对list进行随机访问操作,效率则不行。当我们从档案中读取分数,希望从高到低排列,那么读入一个分数
//便可能需要将它随机插入到容器
//deque对于前端的插入,执行末端删除操作,效率更高
//使用顺序性容器,首先必须包含相关的头文件。
#include<vector>
#include<list>
#include<deque>
list<string> slist;
vector<int> ivec;//产生空容器
list<int> ilist(1024);
vector<string> svec(32);
//产生特定大小的容器
//产生特定大小的容器,并且指定初值
vector<int> ivec(10.-1);
list<string> slist(16,"unassigned"};
//通过一对iterator产生容器,
int ia[8]=[1,1,2,3,5,8,13,21};
vector<int> fib(ia,ia+8);
//根据某个容器产生出新容器。复制原容器内的元素,作为新容器的初值
list<string> slist;
list<string> slist2(slist);
//push_back(),pop_back();push_front(),pop_front();读取最前端的值用front(),读取最后端的值用back()
#include<deque>
deque<int> a_line;
int ival;
while(cin>>ival)
{
    a_line.push_back(ival);
    int curr_value=a_line.front();
    a_line.pop_front();
}
//通用insert()
iterator insert(iterator position,elemType value)//将value插入position之前,并且返回插入元素的iterator
list<int> ilist;
list<int>::iterator it=ilist.begin();
while(it!=ilist.end())
{
    if(*it>=ival)
    {
        ilist.insert(it,ival);
        break;
    }
    ++it;
}
if(it==ilist.end())
 ilist.push_back(ival);
void insert(iterator position,int count,elemType value)//在position前面插入count个元素,这些元素的值都和value相同

    string sval("Part Two");
    list<string> slist;
    list<string>::iterator
        it=find(slist.begin(),slist.end(),sval);
    slist.insert(it,8,string("dummmy");

void insert(iterator1 position,iterator2 first,iterator2 last)//在position前面插入从first到last的所有元素
int ia1[7]={1,1,2,3,5,55,89};
int ia2[4]={8,13,21,34};
list<int> elems(ia1,ia1+7);
list<int>::iterator it=find(elems.begin(),elems.end(),55);
elems.insert(it,ia2,ia2+4);
iterator insert(iterator position)//可在position之前插入元素
iterator erase(iterator posit)//可删除posit所指的元素
//例如list
list<string>::iterator
it =find(slist.begin(),slist.end(),str);
slist.erase(it);
iterator erase(iterator first,iterator last)//可删除first到last范围内的数
list<string>::iterator
first=slist.begin(),last=slist.end();
list<string>::iterator it1=find(first,last,str);
list<string>::iterator it2=find(first,last,sval);
slist.erase(it1,it2);//list不支持iterator是偏移
//所以必须传入it1和it2




基本就是把书上的一些重点注释了,估计只有我一个人可以看懂o_o!
并不是完整的程序,一些代码片而已,可是编程这东西,真的是要动手,动手,动手啊啊啊啊啊去!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值