【C/C++】从API学习STL algorithm 001(for_each、find、find_if、find_end、find_first_of 快到碗里来(◕ᴗ◕✿)

今天的主题是, STL algorithm :)~

algorithm概述

  • The header <algorithm> defines a collection of functions especially designed to be used on ranges of elements.(这些函数/算法专门用于操作范围元素,而STL容器就是存储一连串/范围数据的)
  • A range is any sequence of objects(对象序列) that can be accessed through iterators or pointers, such as an array or an instance of some of the STL containers. Notice though(不过请注意), that algorithms operate through iterators directly on the values, not affecting in any way the structure of any possible container (it never affects the size or storage allocation of the container 用STL algorithm函数并不会影响容器的大小和内存空间分配).
  • algorithm是STL头文件中最大的一个,其中常用到的功能涉及到比较、交换、查找、遍历、复制、修改、反转、排序、合并等
  • 使用algorithm中的算法需要【#include <algorithm>】

  Functions in <algorithm> 算法分类

001 第一部分 不会修改字符序列的操作

for_each(first, last, function )

  • 传入迭代器范围[first, last) 并对其中的元素进行function操作,即将函数作用于容器范围(Apply function to range)
  • Applies function f to each of the elements in the range [first,last).
  • first, last

    Input iterators to the initial and final positions in a sequence. The range used is [first,last), which contains all the elements between first and last, including the element pointed by first but not the element pointed by last.

  • function

    Unary【一元】 function taking an element in the range as argument. This can either be a pointer to a function or an object whose class overloads operator(). function可以是一个指向函数的指针或者是一个重写了operator()函数的对象

  • Its return value, if any, is ignored.    for_each函数的返回值,如果没有返回值,忽略即可

/**
 * Created By Liu Xianmeng On 2022/12/9
 * 【for_each函数】  顾名思义它是遍历每个元素的意思 但注意这里的“每个”
 *                 针对的是传入的迭代器范围内的元素
 *                 
 *                 它的第三个参数可以传入一个结构体,结构体中定义一个操作函数,对迭代器中的每个进行操作
 *                 也可以传入一个函数,函数定义对每个遍历元素的操作
 *                 
 *                 不错,这个函数挺妙的!
 */
#include <bits/stdc++.h>
using namespace std;
void myfunction (int i) { // 定义函数传入for_each看起来更加简洁
    cout << " " << i*i;
}
struct myclass { 
    void operator() (int i) {cout << " " << i;}
} myobject;
int main () {
    vector<int> v;
    v.push_back(10); v.push_back(20); v.push_back(30);
    cout << "v contains:(迭代器范围的元素被平方后输出)";
    for_each (v.begin(), v.end()-1, myfunction);
    // or:
    cout << "\nv contains:(迭代器范围的元素直接输出,不做其他处理)";
    for_each (v.begin(), v.end(), myobject);
    cout << endl;
    /* 【打印结果】
        v contains: 100 400
        v contains: 10 20 30    
     */
    return 0;
}

string容器使用for_each函数:

string v = "BigXMeng888";
cout << "v contains:(迭代器范围的元素ASCLL码+1后输出)";
for_each (v.begin(), v.end(), func);
cout << "\nv contains:(迭代器范围的元素ASCLL码-1后输出)";
for_each (v.begin(), v.end(), operation);
/* 【打印结果】
    v contains:(迭代器范围的元素ASCLL码+1后输出) C j h Y N f o h 9 9 9
    v contains:(迭代器范围的元素ASCLL码-1后输出) A h f W L d m f 7 7 7
 */

find(first, last, value)

  • Find value in range (查找字面值val)
  • Returns an iterator to the first element in the range [first,last) that compares equal to value, or last if not found. 返回一个指向找到的value的迭代器,如果没找到value,返回last
  • The behavior of this function template is equivalent to:

/**
 * Created By Liu Xianmeng On 2022/12/8
 */
#include <bits/stdc++.h>
using namespace std;
int main () {
    int ints[] = { 10, 20, 30 ,40 };
    int *p;
    // pointer to array element(对find函数传入指针):
    p = find(ints,ints+4,30); // 在ints数组中找value === 30
    ++p; // 让p指向下一个位置 也就是指向40
    cout << "The element following 30 is " << *p << endl;
    vector<int> v (ints,ints+4); // 创建一个元素内容和ints完全一样的vector
    vector<int>::iterator it;
    // iterator to vector element(对find函数传入迭代器):
    it = find (v.begin(), v.end(), 30);
    ++it; // 让返回的迭代器指向下一个元素 也就是40
    cout << "The element following 30 is " << *it << endl;
    return 0;
    /* 【Result】
        The element following 30 is 40
        The element following 30 is 40
     */
}

find_if(first, last, pred)

Find element in range (条件查找

  • Returns an iterator to the first element in the range [first,last) for which applying pred to it, is true. 条件从何而来?所谓的条件,就是看 *first 经过pred函数处理后是否返回true,返回true则找到目的元素(就是对*first进行断言,为真则找到,return first;find_f函数结束)
  • Pred : Unary(一元) predicate taking an element in the range as argument, and returning a value indicating the falsehood (with false, or a zero value) or truth (true, or non-zero) of some condition applied to it. This can either be a pointer to a function or an object whose class overloads operator(). 这里的Predicate就是一个判断是否满足条件的一元函数(函数的内容可以自定义),这个函数也可以是一个指向断言函数的指针,或者是一个重载了operator()函数的对象,这个对象可以是一个结构体,或者类的实体。
  • If pred is false for all elements, the function returns last. 如果没有找到符合条件的elem则返回last
/**
 * Created By Liu Xianmeng On 2022/12/9
 */
#include <bits/stdc++.h>
using namespace std;
bool IsOdd (int i) { // Predicate函数
    return ((i%2)==1);
}
int main () {
    vector<int> v;
    vector<int>::iterator it;
    v.push_back(10); v.push_back(25); v.push_back(40); v.push_back(55);
    // 返回满足条件的元素对应的迭代器
    it = find_if (v.begin(), v.end(), IsOdd);
    cout << "The first odd value is " << *it << endl;
    return 0;
}
/* 【Result】
    The first odd value is 25
*/

find_end(..)找到最后一个匹配的范围的第一个元素并返回其下标

函数声明:

template <class ForwardIterator1, class ForwardIterator2>
   ForwardIterator1 find_end ( ForwardIterator1 first1, ForwardIterator1 last1,
                               ForwardIterator2 first2, ForwardIterator2 last2 );

template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
   ForwardIterator1 find_end ( ForwardIterator1 first1, ForwardIterator1 last1,
                               ForwardIterator2 first2, ForwardIterator2 last2.
                               BinaryPredicate pred );

说明:

  • Find last subsequence in range 
  • Searches the range [first1,last1) for the last occurrence of the sequence defined by [first2,last2), and returns an iterator to its first element.  在range===[first1, last1)中查找目标子序列[first2, last2), 如果找到,返回指向range中出现的最后一个子序列的第一个元素的迭代器
  • The sequence of elements in [first2,last2) is compared to the possible subsequences of successive elements within [first1,last1) by either applying the == comparison operator to each element, or the template parameter comp (for the second version).  [first2,last2)中的元素序列与[first1,last1)中连续元素的可能子序列进行比较,方法是对每个元素应用==比较操作符,或者使用模板参数comp(对于第二个版本)。
  • pred 的功能可以自行定义 (见下代码)

代码:

/**
 * Created By Liu Xianmeng On 2022/12/9
 */
#include <bits/stdc++.h>
using namespace std;
bool pred(int i, int j) { // pred函数的功能可以自定
    // 这里定义为原序列的某个子序列的每个元素都是要查找的子序列的2倍
    return (i==j*2); // 才满足条件
}
int main () {
    int I[] = {1,2,3,4,5,1,2,3,4,5};
    vector<int> v (I,I+10);
    vector<int>::iterator it;
    int match1[] = {1,2,3};
    // using default comparison:
    it = find_end (v.begin(), v.end(), match1, match1+3);
    if (it!=v.end())
        cout << "match1 last found at position " << int(it-v.begin()) << endl;
    vector<int> v2 = {2,4,6,1,1,1,1,1,1,1,1,1,2,4,6,1,1};
    int match2[] = {1,2,3};
    // using predicate comparison(使用谓词比较):
    it = find_end (v2.begin(), v2.end(), match2, match2+3, pred);
    if (it!=v.end())
        cout << "match2 last found at position " << int(it-v2.begin()) << endl;
    return 0;
}
/* 【Result】
    match1 last found at position 5   // v中的最后一个{1,2,3}序列的1所在的下标位置为5
    match2 last found at position 12  // v2中的最后一个{2,4,6}序列的2所在的下标位置为12
*/

find_first_of 找到第一个匹配的范围的第一个元素并返回其下标

【函数声明如下】
template <class ForwardIterator1, class ForwardIterator2>
   ForwardIterator1 find_first_of ( ForwardIterator1 first1, ForwardIterator1 last1,
                                    ForwardIterator2 first2, ForwardIterator2 last2 );

template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
   ForwardIterator1 find_first_of ( ForwardIterator1 first1, ForwardIterator1 last1,
                                    ForwardIterator2 first2, ForwardIterator2 last2,
                                    BinaryPredicate pred );

代码验证:

#include <iostream>
#include <algorithm>
#include <cctype>
#include <vector>
using namespace std;
// 用于验证条件的函数(要求被查找的范围[match, match+n)的每一个元素在原序列中都满足所组构成的子序列)
bool comp_case_insensitive (char c1, char c2) {
    // 此条件函数判断两个被比较的序列字符的字母是否一致(都转换为小写字母进行比较)
    return (tolower(c1)==tolower(c2));
}
int main () {
    int mychars[] = {'A','b','c','A','B','C'};
    vector<char> v (mychars,mychars+6);
    vector<char>::iterator it;
    int match[] = {'A','B','C'};
    // 在v中查找第一个ABC子序列 并返回指向此序列的第一个元素的迭代器
    it = find_first_of (v.begin(), v.end(), match, match+3);
    if (it!=v.end()) // 返回的结果it不等于v.end()则说明找到
        cout << "first match is: " << *it << endl;
    // 在v中查找第一个abc子序列(使用条件函数作为第5个参数) 并返回指向此序列的第一个元素的迭代器
    it = find_first_of (v.begin(), v.end(),
                        match, match+3, comp_case_insensitive);
    if (it!=v.end()) // 同上
        cout << "first match is: " << *it << endl;
    /* 【打印结果】
        first match is: A
        first match is: A
     */
    return 0;
}

(后续更新...)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值