欢迎来到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++标准库中用于比较两个值并返回较小值的函数。这个函数有两个版本,一个接受两个参数,另一个接受一个序列(容器)作为参数。
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;
}
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_argument
或std::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::vector
、std::set
、std::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;
}
上述代码首先创建了两个向量vec1
和vec2
,并初始化它们为{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_assignable
和 std::is_move_constructible
是<type_traits>
头文件中的两个模板类,用于检查类型是否支持移动赋值和移动构造。
虽然这两个模板类都用于检查类型是否具有某种移动特性,但它们的功能有所不同:
-
std::is_move_assignable<T>
:用于检查类型T
是否支持移动赋值操作。如果类型T
具有可移动赋值运算符(即有合适的移动赋值函数),则std::is_move_assignable<T>::value
的值为true
,否则为false
。 -
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);
其中,first
和last
表示要检查的范围,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
函数执行的是一个顺序操作,不保证并行执行。