初识泛型算法
理解算法的最基本方法是了解他们是否读取元素、改变元素或是重排元素顺序!
只读算法
#include<iostream> #include<numeric> using namespace std; //对vec中的元素求和,初值是0 int sum=accumulate(vec.cbegin(), vec.cend(), 0);
这里面第三个参数决定了函数使用哪个加法运算符以及返回值类型。
算法和元素类型
string sum=accumulate(v.cbegin(), v.cend(), string(""));
这里有一个问题,就是后面stiring("")为什么要这样创建一个字符串呢?
string sum=accumulate(v.cbegin(), v.cend(), "");
这样看起来是对的,其实是有问题的。
//错误:const char*上没有定义“+”运算符 string sum=accumulate(v.cbegin(), v.cend(), "");
原因就是:如果我们传递一个字符串字面值,用于保存和的对象的类型将会是const char*。可是const char* 是没有“+”运算符的
操作两个序列的算法
//roster2中的元素数目应该至少与roster1一样多 equal(roster1.cbegin(), roster.cend(), roster2.begin());
三个参数,都是迭代器,前两个和上面一样表示范围,后一个表示第二个序列的开始。
由于equal调用迭代器完成的,所以我们可以通过调用equal来比较两个不同类型的容器中的元素。
要求!!!!第二个序列至少和第一个一样长
写容器元素的算法
一些算法会自己向输入范围书写元素。
如:
fill(vec.begin(), vec.end(), 0); //将每一个元素重置为0 //将容器的一个子序列设置为10 fill(vec.begin(), vec.begin()+vec.size()/2, 10);
算法不检查写操作
vector<int> vec; //空vector //使用vec,赋予它不同值 fill_n(vec.begin(), vec.size(), 0); //将所有元素重置为0
//函数fill_n假定写入指定个元素是安全的。 fill_n(dest, n, val)
这里有一个很容易犯的问题,在空容器上调用fill_n
vector<int> vec; //空向量 //灾难:修改vec中的10个(不存在)元素 fill_n(vec.begin(), 10, 0);
介绍back_inserter
这个是插入迭代器!!!插入!!!插入!!插入!恩就是插入元素的意思。
这个玩意是定义在iterator头文件中的一个函数!
vector<int> vec; //空向量 auto it=back_inserter(vec); //通过它赋值会将元素插入到vec中!! *it=42; //ok现在vec中有一个叫42的值了!!! //我们常用back_inserter来创建一个迭代器,作为算法的目的位置来使用 vector<int> vec; //空向量 //正确:back_inserter创建一个插入迭代器,可用来向vec添加元素 fill_n(back_inserter(vec), 10, 0); //这里由于每次调用都会用到back_inserter返回的是push_back //最终这个语句向vec的末尾添加了10个为0的元素
拷贝算法
三个参数!!copy算法前两个迭代器表示范围,后面的表示目标的起始序列,中标!!一枪中标
int a1[]={0,1,2,3,4,5,6,7,8,9}; int a2[sizeof(a1)/sizeof(*a1)]; //a2与a1大小一样 //ret指向拷贝到a2的尾元素之后的位置 auto ret=copy(begin(a1), end(a1), a2); //吧a1的内容拷贝给a2
这里还可以给大家介绍一个好玩的额泛型算法!!!
那就是!!
就是!!
是!!
哈哈
就是replace
看到序列那个不顺眼,就叫replace爸爸把它换了吧!!!
//将所有的0换成42 replace(ilst.begin(), ilst.end(), 0, 42); //如果希望还是保留原来的序列,来一个新序列保存修改后的数据 //那么这里还有一个好玩意 replace_copy(ilst.cbegin(), ilst.cend(), back_inserter(ivec), 0, 42); //调用后ilst没有改变,ivec包含ilst的一份拷贝,不过原来在ilst中值为0的元素ivec //中都变成42
恩,从这里可以得到一个结论:
很重要!!!
是的!
那就是编书的那个家伙特别喜欢42这个数字,不知道是不是那家伙的幸运数字啊,但是特么有点大了,我们的幸运数字不都是0到9的吗!!!!
重排容器元素的算法
那就是!!
又来了,好吧就是:sort会重排输入序列中的元素是利用“<”来实现的;
消除重复元素
//好的 ,看个使用sort的案例 void elimDups(vector<string> &words) { //这命名,特么不是欺负我不懂英语么 //安字典排序words,以便查找重复单词 sort(words.begin(), words.end()); //unique重排输入范围,使得每个单词只出现一次 //排列在范围的前部,返回指向不重复区域之后一个位置的迭代器 auto end_unique=unique(words.begin(), words.end()); //使用向量操作erase删除重复单词 words.erase(end_unique, words.end()); }
sort就理解为从小到大排序吧,简单好记易得分,就像高中数学,字大,空多,题少,嘿嘿!!
就是不会做
使用unique
这个会消除相邻的重复项,返回不重复值范围末尾的迭代器。
PS:今天时间比较充足,所以就比较轻松,希望大家喜欢!!!
这里补充一句,要好好树立自己的目标,目标要时刻提醒自己,不能走着走着就迷路了,计划要明确,不然无处下牙,慢慢培养自己,每日三省吾身!!!