essential c++ 第三章整理

1.指针的运算

  • 可以对指针使用下标运算符

下标运算符就相当于在起始地址的基础上加上索引值,产生某个元素的地址

#include<iostream>
using namespace std;
int main(){
	int a[]={1,2,3,4,5};
	int *p=a;
	cout << p[1];//或者cout << *(p+1); cout<< *p[1]是错误的
}

上面程序的输出为2,

所以

p[1] = *(p+1)

对于书中的对vector和array的泛型算法:

template <typename elemtype>
elemtype* find(const elemtype *array,int size,const elemtype &value){ // array就是数组的首地址
	if(!array || size<1){
		return 0;
	}
	for(int i=0;i<size;i++){
		if(array[i]==value)
			return &array[i];     //可以看出array[i]是一个具体的值。而不是对象,就相当于数组一样
	}
	return 0;
}

除了使用指针的下标计算外,还可以:

template <typename elemtype>
elemtype* find(const elemtype *array,int size,const elemtype &value){
	if(!array || size<1){
		return 0;
	}
	for(int i=0;i<size;i++,++array){  //由此 for语句不仅仅是每个部分一句,可以多句
		if(*array==value)             //由地址提领到他的值
			return array;             //返回当前地址
	}
	return 0;
}

2.iterator

需要实现的功能

for(iter=vec.begin();iter !=vec.end();++iter){
    cout << *iter << endl;
}
vector<int> vec;
vector<int> ::iterator iter=vec.begin()

可以通过iter调用vector的函数

iter->size()

3.容器公用的操作

4.使用顺序性容器

定义容器的方式

// 产生空的容器
vector<int> vec;
list<string> ilist;

//产生特定大小的容器,每个元素为默认值,int double默认值为0
list<int> ilist(1024);
vector<string> ivec(32);

//产生特定大小的容器,并为每个元素赋初值
vector<int> ivec(10,-1)
list<string> slist(16,"abcdefg")

//通过对iterator产生容器
int ia[8]={1,2,3,4,5,6,7,8}
vector<int> fib(ia,ia+8)

//通过一个容器,产生另外一个容器
list<string> slist;
list<string> slist2(slist)

容器的插入和删除的操作

push_back()//末尾插入
pop_back()//末尾删除

5.使用泛型算法

6.设计泛型算法

  • 设计一个程序,给与一个vector,现在返回一个vector,内含原vector中所有小于10的元素
vector<int>less_than_10(const vector<int> &vec){
    vector<int> nvec;
    for (int i = 0; i < vec.size(); ++i) {
        if(vec[i]<10)
            nvec.push_back(vec[i]);
    }
    return nvec;
}
  • 现在要去改进程序,可以指定边界数,同时可以指定大于、小于、等于
vector<int> filter(const vector<int> &vec,int value,bool (*pred)(int,int)){
    vector<int> nvec;
    for(int i=0;i<vec.size();i++){
        if(pred(vec[i],value))
            nvec.push_back(vec[i]);
    }
    return nvec;
}

bool less_than(int a,int b){
    return a<b ? true:false;
}

bool more_than(int a,int b){
return a>b ? true:false;
}

这里使用函数指针,通过函数指针可以达到指定大于小于的作用,记住,函数名和数组名一样,本质上就是指针,是一个地址。

  • 实际的完整程序
#include <iostream>
#include <vector>
using namespace std;
vector<int>less_than_10(const vector<int> &vec){
    vector<int> nvec;
    for (int i = 0; i < vec.size(); ++i) {
        if(vec[i]<10)
            nvec.push_back(vec[i]);
    }
    return nvec;
}

//使用函数指针

vector<int> filter(const vector<int> &vec,int value,bool (*pred)(int,int)){
    vector<int> nvec;
    for(int i=0;i<vec.size();i++){
        if(pred(vec[i],value))
            nvec.push_back(vec[i]);
    }
    return nvec;
}

bool less_than(int a,int b){
    return a<b ? true:false;
}

bool more_than(int a,int b){
return a>b ? true:false;
}

//vector<int> avec=filter(big_vec,value,less_than)
int main(){

    int a[6];
    for(int i=0;i<6;i++){
        int b;
        cin >> b;
        a[i]=b;
    }
    vector<int>vec(a,a+6);
    vector<int> svec=filter(vec,5,less_than);
    for(int i=0;i<svec.size();i++){
        cout << svec[i] << endl;
    }
}
  • function object
//头文件
#include<functional>

可以实现:

sort(vec.begin(),vec.end(),greater<int>)

通过greater,可以使得排列之后的容器是从大到小

常用的有:

算术运算符:plus<type>、minus<type>、negate<type>、multiplies<type>、divides<type>
关系运算符:less<type>、less_equal<type>、greater<type>、greater_equal<type>、        
           equal<type>、not_equal_to<type>
逻辑运算符:logical_and<type>、logical_or<type>、logical_not<type>
  • function object adapter

例如上面的less<type>,是希望外界传入两个值,如果符合要求,就返回true,而我们设置的filter函数事希望传入的一个值一直和设定的值比较,所以需要使用adapter,将less<type>转化为一元运算符。

使用bind1st将值绑定到第一操作数,bind2nd将值绑定到第二操作数。

vector<int> filter(const vector<int> &vec,int value,less<int> &lt){
    vector<int> nvec;
    vector<int> ::iterator iter=nvec.begin();
    while((iter=find_if(iter,nvec.end(),bind2nd(lt,value)))!=nvec.end()){
        nvec.push_back(*iter);
        iter++;
    }

    return nvec;
}

7.map

map为一对数值,包含key和value

map<string,int> words
words["vermeer"]=1;
string tword;
while(cin >> tword)
    words[tword]++;
  • 注意一下要点
int count=0;
if(!(count=words["vermeer"]))

这种做法,当words中并不包含vermeer这个键的时候,会自动的加入到words中,同时value会被置为默认值。

  • map.find()
words.find("vermeer")

返回一个iterator,指向当前的pair,如果不存在,则返回end()

  • map.count()
words.count["vermeer']

返回数量

注意:vector中没有count和find这个类函数,就是不能使用vector.count()的方式,但是可以用algorithm中的函数

8.set

9.iterator inserter

首先要包含#include<iterator>

如以下程序:

vector<int> filter (const vector<int> &vec,const int val,less<int> &pred){
    vector<int> ::iterator first=vec.begin();
    vector<int>::iterator last=vec.end();
    vector<int> nvec;
    vector<int> ::iterator at=nvec.begin();
    while((first=find_if(first,last,bind2nd(pred,val))) !=last){
        *at++=*first++;
    }
}

这个filter函数采取的方式是,将符合条件的每一个元素一一赋值给一个新的vector,而不是push_back,因此这个新的vector的尺寸我们并不知道,而在程序中取地址at时,通过at++遍历vector的每一个存储空间,又因为每个固定vector的大小,所以可能会出错。我们必须要保证vector足够大

因此标准库提供了insertion adapter,避免使用容器的assignment 运算符。

  • back_inserter()

以容器的push_back代替assignment运算符

list<int> lst = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
copy(lst.begin(), lst.end(), back_inserter(lst2));
//lst2包含10,1,2,3,4,5,6,7,8,9

将lst中的元素插入到lst2中

  • inserter()
list<int> lst = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
copy(lst.cbegin(), lst.cend(), inserter(lst3, lst3.begin()));
//lst3包含1,2,3,4,5,6,7,8,9,10

将lst插入到lst3指定位置之前

  • front_inserter
list<int> lst = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
list<int> lst4={10};
copy(lst.cbegin(), lst.cend(), front_inserter(lst4));
//lst4包含9,8,7,6,5,4,3,2,1,10

将每个元素一次插入到lst4第一个元素前

10.iostream iterator

标准库定义的iostream iterator,包括istream_iterator 和 ostream_iterator,分别支持单一类型的元素读取和写入

#include<iterator>

#include<iostream>
#include<iterator>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;
int main(){
  //提供一个first iterator,将is定义为标准输入
	istream_iterator<string> is(cin);

  //同时还要有last iterator,表示要读取的最后一个元素的下一位置
	istream_iterator<string> eof;

	vector<string> text;

  //通过copy,将cin到eof的元素插入到text中
	copy(is,eof,back_inserter(text));

	sort(text.begin(),text.end());
	
//定义一个输出,将text的元素复制给os 即标准输出cout,同时还有空格
	ostream_iterator<string> os(cout," ");
	copy(text.begin(),text.end(),os );
}

 在实现标准输入输出的同时,还可以从文件中读取,并写入到文件中

#include<iostream>
#include<iterator>
#include<fstream>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;
int main(){
	ifstream in_file("input_file.txt");
	ofstream out_file("output_file.txt"); 
	
	istream_iterator<string> is(in_file);
	istream_iterator<string> eof;
	vector<string> text;
	copy(is,eof,back_inserter(text));
	sort(text.begin(),text.end());
	
	ostream_iterator<string> os(outfile," ");
	copy(text.begin(),text.end(),os );
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值