C++ algorithm算法小结(三)

今天继续带来一些常用的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结尾,最后就可以得到删除之后该有的形式了。

猜你喜欢

转载自blog.csdn.net/weixin_40349531/article/details/88541151
今日推荐