C++那些让我们偷懒的函数

在这里插入图片描述

欢迎来到Cefler的博客😁
🕌博客主页:那个传说中的man的主页
🏠个人专栏:题目解析
🌎推荐文章:题目大解析(3)

在这里插入图片描述


前言
让我们康康c++为我们提供的懒人函数吧,后续会不间断补充。


👉🏻max_element

使用std::max_element函数找到容器中的最大元素:

#include <iostream>
#include <algorithm>
#include <vector>

int main() {
    std::vector<int> numbers = {5, 3, 8, 2, 9, 1};
    
    auto maxElement = std::max_element(numbers.begin(), numbers.end());
    
    std::cout << "最大值是:" << *maxElement << std::endl;
    
    return 0;
}

👉🏻min_element

std::min函数是C++标准库中用于比较两个值并返回较小值的函数。这个函数有两个版本,一个接受两个参数,另一个接受一个序列(容器)作为参数。

  1. std::min函数接受两个参数,用于比较两个值的大小,并返回较小的那个值。它可以用于大多数内置类型和用户定义的类型,只要该类型支持小于运算符(<)。
#include <iostream>
#include <algorithm>

int main() {
    int a = 10;
    int b = 20;
    
    int minValue = std::min(a, b); // 返回10
    
    double x = 3.14;
    double y = 2.71;
    
    double minDoubleValue = std::min(x, y); // 返回2.71
    
    return 0;
}
  1. std::min函数还可以接受一个序列(容器),用于查找序列中的最小值,并返回该值。它需要两个迭代器作为参数,分别表示序列的起始位置和结束位置。
#include <iostream>
#include <algorithm>
#include <vector>

int main() {
    std::vector<int> numbers = {5, 3, 8, 2, 9, 1};
    
    auto minValue = std::min_element(numbers.begin(), numbers.end()); // 返回1
    
    return 0;
}

上述代码中,std::min_element函数查找numbers容器中的最小值,并返回一个迭代器,该迭代器指向最小值所在的位置。

需要注意的是

std::min_element函数返回的是一个迭代器,用于指向容器中的最小元素。因为容器中的元素类型可能各不相同,所以无法事先确定返回值的具体类型。为了方便,我们可以使用auto关键字将返回值的类型推断出来。

auto是C++11引入的关键字,用于自动推断变量的类型。通过使用auto关键字,编译器会根据初始化表达式的类型来推断变量的类型,省去了显式指定变量类型的麻烦。

在上述代码中,std::min_element返回的迭代器可以指向任何类型的元素,因此我们不确定具体的类型是什么。为了方便编写代码并保持代码的通用性,我们可以使用auto关键字来让编译器自动推断返回值的类型。

#include <iostream>
#include <algorithm>
#include <vector>

int main() {
    std::vector<int> numbers = {5, 3, 8, 2, 9, 1};
    
    auto minValue = std::min_element(numbers.begin(), numbers.end()); // 返回1
    
    return 0;
}

在上述代码中,minValue的类型会被自动推断为std::vector<int>::iterator,这是由于numbers容器是std::vector<int>类型,并且std::min_element返回的是该容器的迭代器。

使用auto关键字可以简化代码,并且使代码更加通用和易读。当我们不确定变量的具体类型时,使用auto是一个很好的选择。

👉🏻std::stoi

在C++中,可以使用std::stoi()函数将std::string类型的对象转换为整数。

#include <iostream>
#include <string>

int main() {
    std::string str = "12345";
    
    int num = std::stoi(str);
    
    std::cout << "Converted number: " << num << std::endl;
    
    return 0;
}

在上述代码中,我们将字符串"12345"赋值给std::string对象str,然后使用std::stoi()将其转换为整数,并将结果赋值给num变量。最后,通过输出流std::cout打印出转换后的整数结果。

需要注意的是,std::stoi()函数在转换过程中会忽略字符串前导的空格,并且如果字符串中有非数字字符,则转换会停止并返回有效数字部分。如果无法转换为整数,则会抛出std::invalid_argumentstd::out_of_range异常。

另外,还有其他类似的函数可以将std::string转换为其他类型,比如std::stol()用于长整型、std::stof()用于单精度浮点型、std::stod()用于双精度浮点型等。这些函数都属于C++标准库的一部分,可以在头文件<string>中找到它们的声明。


std::stoi()函数会忽略整数字符串前方的空格并将其作为有效数字部分进行解析。因此,如果传入的字符串是"00123",它会被解析成整数123,转换成功。

下面是一个例子:

#include <iostream>
#include <string>

int main() {
    std::string str = "00123";
    
    int num = std::stoi(str);
    
    std::cout << "Converted number: " << num << std::endl;
    
    return 0;
}

输出:

Converted number: 123

需要注意的是,如果字符串前方有非零数字的前导零,则会被忽略。比如字符串"0123"会被解析成整数123,而不是123

👉🏻std::set_intersection——两个容器找交集

C++标准库提供了多种从两个容器中找交集的函数,其中一个常用的函数是std::set_intersection。这个函数可用于查找两个有序容器(如std::vectorstd::setstd::map)中的交集,并将结果放入一个输出迭代器所指定的位置。下面是一段使用std::set_intersection函数的示例代码:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> vec1 = {1, 2, 3, 4, 5};
    std::vector<int> vec2 = {3, 4, 5, 6, 7};
    std::vector<int> intersection;

    std::set_intersection(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), std::back_inserter(intersection));

    std::cout << "Intersection: ";
    for (const auto& num : intersection) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

上述代码首先创建了两个向量vec1vec2,并初始化它们为{1, 2, 3, 4, 5}{3, 4, 5, 6, 7}

然后,我们创建了一个名为intersection的向量来存储两个向量之间的交集。接着,我们使用std::set_intersection函数将两个向量的交集放入intersection向量中。

最后,我们输出交集的值。

输出:

Intersection: 3 4 5 

需要注意的是,为了使用std::set_intersection函数,两个容器必须是有序的,也就是说,它们内部的元素已经排好序了。如果容器中的元素没有排序,则必须首先对它们进行排序操作。

另外,需要指定一个输出迭代器来存储交集元素。在上述代码中,我们使用std::back_inserter函数和intersection向量的begin函数来创建一个输出迭代器,它会将数据插入intersection向量的尾部。你也可以使用其他类型的输出迭代器来保存结果。

👉🏻std::is_move_assignable和std::is_move_constructible

std::is_move_assignablestd::is_move_constructible<type_traits>头文件中的两个模板类,用于检查类型是否支持移动赋值和移动构造。

虽然这两个模板类都用于检查类型是否具有某种移动特性,但它们的功能有所不同:

  1. std::is_move_assignable<T>:用于检查类型 T 是否支持移动赋值操作。如果类型 T 具有可移动赋值运算符(即有合适的移动赋值函数),则 std::is_move_assignable<T>::value 的值为 true,否则为 false

  2. std::is_move_constructible<T>:用于检查类型 T 是否支持移动构造操作。如果类型 T 具有可移动构造函数,则 std::is_move_constructible<T>::value 的值为 true,否则为 false

因此,std::is_move_assignable 判断的是类型是否支持移动赋值操作,而 std::is_move_constructible 判断的是类型是否支持移动构造操作。

需要注意的是,一个类型既可以支持移动赋值操作,也可以支持移动构造操作,也可以同时不支持两者。因此,在需要比较特定类型的移动特性时,可以根据具体需求使用这两个模板类进行检查。

下面是一个示例,演示了如何使用这两个模板类:

#include <iostream>
#include <type_traits>
#include <vector>

int main() {
    bool isMoveAssignable = std::is_move_assignable<std::vector<int>>::value;
    bool isMoveConstructible = std::is_move_constructible<std::vector<int>>::value;

    std::cout << "isMoveAssignable: " << isMoveAssignable << std::endl;
    std::cout << "isMoveConstructible: " << isMoveConstructible << std::endl;

    return 0;
}

输出结果将会指示 std::vector<int> 是否支持移动赋值和移动构造操作。

👉🏻std::sort对字符串的排序

std::sort 对字符串排序的默认方式是按照字典序(即ASCII码值)进行排序。如果想要按照字符串长度排序,可以自定义一个排序函数,将排序依据设置为字符串的长度。

std::vector<std::string> 为例,假设我们要按照字符串长度从小到大排序,可以先定义一个比较函数如下:

bool cmp(const std::string& a, const std::string& b) {
    return a.length() < b.length();
}

这里使用了字符串的 length() 方法来获取字符串的长度,并将比较结果返回。然后将该函数传递给 std::sort 函数即可按照字符串长度从小到大排序:

#include <algorithm>
#include <iostream>
#include <vector>

bool cmp(const std::string& a, const std::string& b) {
    return a.length() < b.length();
}

int main() {
    std::vector<std::string> strs = {"aa", "b", "ccc", "dddd"};

    std::sort(strs.begin(), strs.end(), cmp);

    for (const auto& str : strs) {
        std::cout << str << " ";
    }
    std::cout << std::endl;

    return 0;
}

在输出中,按照长度从小到大排序的结果是 b aa ccc dddd ,其中每个字符串都按照长度递增的顺序排列。

👉🏻 std::accumulate (容器元素求和)

在 C++ 标准库中,没有提供直接用于求和容器元素的函数。但你可以使用标准库的算法(algorithm)和迭代器(iterator)来实现求和操作。

以下是一个示例,展示了如何使用 std::accumulate 算法来求和一个容器中的元素:

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>

int main() {
    std::vector<int> nums = {1, 2, 3, 4, 5};

    // 使用 std::accumulate 求和
    int sum = std::accumulate(nums.begin(), nums.end(), 0);

    std::cout << "Sum: " << sum << std::endl;

    return 0;
}

运行上述代码,将输出:Sum: 15。这里使用了 std::accumulate 算法,它接受一个范围(如容器的起始迭代器和结束迭代器)以及一个初始值,并返回对范围内的元素进行累加后的结果。

通过调用 std::accumulate 并传递容器的开始迭代器和结束迭代器,以及初始值 0,可以计算出容器中元素的总和。

👉🏻std::gcd求最大公约数

C++标准库中提供了一个函数用于求取两个整数的最大公约数,该函数名为std::gcd。你可以通过包含头文件<numeric>来使用这个函数。下面是一个示例代码:

#include <iostream>
#include <numeric>

int main() {
    int a = 36;
    int b = 48;

    int gcd = std::gcd(a, b);

    std::cout << "最大公约数:" << gcd << std::endl;

    return 0;
}

这段代码中,我们使用std::gcd函数求取了36和48的最大公约数,并将结果输出到控制台。在这个示例中,最大公约数为12。

需要注意的是,std::gcd函数要求传入的参数为整数类型,如果你需要计算其他类型(如浮点数)的最大公约数,可以先将其转换为整数再进行计算。

👉🏻all_of

在C++中,all_of是一个算法函数,用于检查给定范围内的所有元素是否都满足某个条件。它的函数原型如下:

template <typename InputIt, typename UnaryPredicate>
bool all_of(InputIt first, InputIt last, UnaryPredicate p);

其中,firstlast表示要检查的范围,UnaryPredicate是一个一元谓词(接受一个参数并返回布尔值)。all_of函数会遍历范围内的每个元素,并将其传递给谓词函数进行判断。只有当所有元素都满足条件时,all_of函数才会返回true;否则,返回false

以下是一个简单的示例代码,演示了如何使用all_of函数:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> numbers = {2, 4, 6, 8, 10};

    bool allEven = std::all_of(numbers.begin(), numbers.end(), [](int n) {
        return n % 2 == 0;
    });

    if (allEven) {
        std::cout << "All numbers are even." << std::endl;
    } else {
        std::cout << "Not all numbers are even." << std::endl;
    }

    return 0;
}

在上面的示例中,all_of函数用于检查numbers容器中的所有元素是否都是偶数。如果都是偶数,则输出"All numbers are even.“;否则,输出"Not all numbers are even.”。

请注意,all_of函数要求范围是有效的(即first必须小于等于last),否则会导致未定义行为。此外,all_of函数执行的是一个顺序操作,不保证并行执行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值