今天继续带来一些常用的algorithm头文件中的算法的个人理解。
一.find
find函数模板的定义如下。返回值是一个迭代器,参数列表,第一个和第二个都是迭代器,第三个是所要寻找的值。如果未找到,则返回值是最后位置的迭代器。
template<class InputIterator, class T>
InputIterator find (InputIterator first, InputIterator last, const T& val)
{
while (first!=last) {
if (*first==val) return first;
++first;
}
return last;
}
通过自己书写代码,观察结果来理解,代码如下:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
vector<string> a{"ab", "bc", "cd", "de"};
auto x = find(a.begin(), a.end(), "ab");
cout << *x << endl;
auto y = find(a.begin(), a.end(), "ef");
cout << *y << endl;
return 0;
}
最后输出"ab",然后在输出迭代器y的对应的值的时候报错,因为输出的是a.end(),不能输出其结果。
二.search
search函数模板的定义如下:
template<class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 search ( ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2)
{
if (first2==last2) return first1; // specified in C++11
while (first1!=last1)
{
ForwardIterator1 it1 = first1;
ForwardIterator2 it2 = first2;
while (*it1==*it2) { // or: while (pred(*it1,*it2)) for version 2
if (it2==last2) return first1;
if (it1==last1) return last1;
++it1; ++it2;
}
++first1;
}
return last1;
}
作用是在first1到last1中间找第一次出现的first2到last2所指代的对象,返回值是first1到last1中第一次出现对应对象的迭代器,否则返回last1。
个人实验代码如下:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string a = "helloworld";
string b = "world";
auto x = search(a.begin(), a.end(), b.begin(), b.end());
for (int i = 0; i < b.size(); i++)
{
cout << *x;
x++;
}
cout << endl;
return 0;
}
输出的结果为“word”(其实是五个字符而不是一个字符串),符合预期。
三.replace
replace函数模板定义为:
template <class ForwardIterator, class T>
void replace (ForwardIterator first, ForwardIterator last,
const T& old_value, const T& new_value)
{
while (first!=last) {
if (*first == old_value) *first=new_value;
++first;
}
}
观察定义可以看到,这个函数模板的作用就是将一个序列里面的所有old_value全部换成new_value;个人实验代码如下:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> tmp{1, 2, 3, 4, 5, 1, 1, 1};
replace(tmp.begin(), tmp.end(), 1, 6);
for (auto x : tmp)
{
cout << x << ' ';
}
cout << endl;
return 0;
}
经过实验最终的输出结果为 [6 2 3 4 5 6 6 6],这里面的所有的1都变成了6,符合预期。
四.remove
remove函数模板的定义如下,参数列表前两个为迭代器,最后一个为需要删除的值。
template <class ForwardIterator, class T>
ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val)
{
ForwardIterator result = first;
while (first!=last) {
if (!(*first == val)) {
*result = move(*first);
++result;
}
++first;
}
return result;
}
那我们做实验如下:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> tmp{1, 1, 1, 2, 3, 4, 1, 5};
auto pend = remove(tmp.begin(), tmp.end(), 1);
for (auto x : tmp)
{
cout << x << ' ';
}
cout << endl;
for (auto x = tmp.begin(); x != pend; x++)
{
cout << *x << ' ';
}
cout << endl;
cout << tmp.size() << endl;
for (auto x : tmp)
cout << x << ' ';
cout << endl;
return 0;
}
对应的输出结果为:
2 3 4 5 3 4 1 5
2 3 4 5
8
2 3 4 5 3 4 1 5
至于结果为什么是这样子,是因为,对于tmp,此函数从头开始遍历,遇到不是对应的要删除的值就赋值给最前面的数字,然后再找第二个不是要删除的值的数赋值给第二个数字,依次类推,当找到完的时候,前四个数字为 2, 3, 4, 5,而后面的四个,其实并没有进行赋值操作,就还是原来的值,为3, 4, 5 ,6。而且在经过了remove函数之后,tmp的size其实是没变化的,还是8,只改变了里面的值。返回值是一个迭代器,因此用一个pend接住这个值,然后再从tmp.begin()开始循环,pend结尾,最后就可以得到删除之后该有的形式了。