您的位置:首页 > 编程语言 > Go语言

generic algorithm

2017-09-13 16:54 155 查看
generic algorithm(泛型算法)

可用于不同元素/容器类型

算法运行于迭代器之上,不会执行容器操作。所以算法不会直接添加或者删除元素。

由于算法可以依靠迭代器完成大部分的操作,所以并不需要依靠容器的类型;但是依赖元素类型提供的操作。

大多数标准库算法对2个迭代器(第2个为尾后迭代器)表示的范围进行操作。

插入算法都假定具有足够空间

对于list和forward_list应优先使用成员函数版本CP369

命名规范

一些算法允许通过重载传递谓词

_if代表函数使用谓词来代替元素值

_copy代表将处理结果写入到额外的目的空间(同时写回输入序列)

形参形式

Func(beg,end,other args);
Func(beg,end,dest,other args);//dest:指定目的位置
Func(beg,end,beg2,other args);
Func(beg,end,beg2,end2,other args);//从beg2开始的空间至少和beg,end一样大


只读算法:

如果算法只访问并不改变元素,建议使用cbegin()和cend()

对于操作2个序列的算法:

序列的容器类型可以不填

用单一迭代器表示第2个序列编译器假定第2个序列和第1个序列一样长。

find

find_if:寻找第一个具有某种特征的值

接收3个参数

第3个参数为谓词

不存在时返回尾后迭代器

accumulate:求和

接收3个参数

第3个参数为和的初值,决定加法运算符的类型和返回类型

序列中的元素类型必须能和第3个参数的类型匹配,并定义了+运算符

equal:比较序列是否相同

接收3个参数

第3个参数为第2个序列的首元素

只写算法:

确保原大小必须等于/大于算法写入的元素数目

编译器假定有足够的空间,不会进行检查

fill:将给定的值赋给序列中的每个元素

接收3个参数

第3个参数被赋值的元素

fill_n

fill_n(dest,n,val)//将从dest开始的n个元素变为val


copy

接收3个参数

第3个参数表示目的序列的起始位置

必须确保目的序列的容量

返回目的迭代器之后的值

int a1[]={0,1,2,3,4};
//保证大小一致
int a2[sizeof(a1)/sizeof(*a1)];
//将a1拷贝给a2
auto ret=copy(begin(a1),end(a1),a2);


replace:将序列中指定的值都替换成新值

接收4个参数

第3个参数表示需要替换的值

replace_copy:将改变后的原序列的备份保存到别的地方

相比replace额外接收第3个迭代器参数指出保存位置

replace_copy( list.cbegin(),list.cend(),
back_inserter(ivec),0,42 );


这里写代码片


排序算法

sort

unique:将重复的元素放在输入序列的最后,返回指向非重复序列之后的迭代器

void fun(vector<string> &word)
{
sort(words.begin(),words.end());
auto end_unique=unique(words.begin(),words.end());
words.erase( end_unique,words.end() );
}


5标准库允许算法提供自己定义的操作来代替运算符

谓词:

返回值可作为条件的表达式

一元谓词:接收1个参数

二元谓词:接收2个参数

例如

//二元谓词
bool isShorter(const string &s1,const string &s2)
{
return  s1.size()<s2.size();
}
sort( words.begin(),words.end(),isShorter );
//该算法保持相等元素的原有顺序
//在此例中相等为长度相同
stable_sort( words.begin(),words.end(),isShorter );


可调用对象:可以使用(args)(调用运算符)

函数:适用于在多个地方重复使用

函数指针

重载调用运算符的类

如果类定义了调用运算符,则该类对象称作函数对象。

例如

struct absInt{
int operator(){int val}const{
return val<0?-val:val;
}
};

int i=-42;
absInt absobj;
//可以像使用函数一样调用该类的对象
int ui=absobj(i);


标准库的函数对象CP510:可以代替运算符

可用于泛型算法的实参

stable_sort(words.begin(),words.end(),Shortstring());


lambda表达式:适用于只需要在少数地方使用

调用形式:指明了返回类型和参数类型

不同类型的可调用对象可以共享同一调用形式。

例如

//虽然执行了不同的算术运算
int add(int i,int j){ return i%j; }
auto mod=[]{int i,int j}{ return i+j; }


函数表:存储指向可调用对象的指针

考虑使用map实现

map< string,function<int(int,int)> > binops;
/*实际存储的是指针(不是函数指针),无法分辨重载函数。考虑输入函数指针或者lambda CP513*/

binops.insert( {"+",add} );
binops["+"](10,5);//指针指向add函数并传入参数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  泛型算法