其他库函数
1. memset()
memset()是一个用于设置内存块值的函数。它的原型定义在<cstring>头文件中,函数的声明如下:
void* memset(void* ptr, int value, size_t num);
memset()函数接受三个参数:
- ptr:指向要设置值的内存块指针
- value:要设置的值,通常是一个整数
- num:要设置的字节数
memset()函数将ptr指向的内存块的前num个字节设置为value的值。它返回一个指向ptr的指针。
memset()函数通常用于初始化内存块,将其设置为特定的值。
例如,如果要将一个整型数组的所有元素设置为0,可以使用memset()函数如下:
int arr[10];
memset(arr, 0, sizeof(arr));
在上述示例中,memset(arr,0,sizeof(arr))将数组arr的所有元素设置为0。需要注意的是,memset()函数对于非字符类型的数组可能会产生未定义行为。
在处理非字符类型的数组时,最好使用C++中的其他方法,如循环遍历来初始化数组。
memset会将每个byte设置为value,赋值的单位是以byte为单位。
#include <bits/stdc++.h>
using namespace std;
int main() {
int a[5];
memset(a, 1, sizeof a);
for(int i = 0; i < 5; ++ i) cout << bitset<32>(a[i]) << '\n';
return 0;
}
输出结果
00000001000000010000000100000001 //等价于16843009
00000001000000010000000100000001
00000001000000010000000100000001
00000001000000010000000100000001
00000001000000010000000100000001
int类型为四个字节,也就是一个int变量是由4个字节来表示的。而memset赋值的操作单位是byte,会将int类型的四个字节分别赋值为value,所以使用memset赋值value,最终的值与value并不一致,而是与字节个数、value两者相关。
但当memset(a, x, sizeof a) x取0、-1是一致的。下面有详细的解释:
针对于int来说,如果为memset(a, 0, sizeof a)
00000000 00000000 00000000 00000000 -每个字节均被赋值为0,四个字节合起来表示int仍然为0
针对于int来说,如果为memset(a, -1, sizeof a)
-1的原码是1000 0001,反码是1111 1110,补码是1111 1111
计算机的存储是以补码类型存储
故补码为:11111111 11111111 11111111 11111111
将其转换为原码
原码为: 10000000 00000000 00000000 00000001
每个字节均被赋值为-1,四个字节合起来表示int仍然为-1
原码->反码:符号位不变,其余取反
反码->补码:符号位不变,+1
补码<->原码:符号位不变,取反+1
2. swap()
swap(T &a,T&b)函数接受两个参数:
- a:要交换值的第一个变量的引用
- b:要交换值的第二个变量的引用
swap()函数通过将第一个变量的值存储到临时变量中,然后将第二个变量的值赋给第一个变量,最后将临时变量的值赋给第二个变量,实现两个变量值的交换。
swap()函数可以用于交换任意类型的变量,包括基本类型(如整数、浮点数等)和自定义类型(如结构体、类对象等)。
以下是一个示例,展示如何使用swap()函数交换两个整数的值:
int a = 10;
int b = 20;
swap(a, b);
3. reverse()
reverse()函数接受两个参数:
1.first:指向容器中要反转的第一个元素的迭代器
2.last:指向容器中要反转的最后一个元素的下一个位置的迭代器
reverse()函数将[first, last)范围内的元素顺序进行反转。也就是说,它会将[first,last)范围内的元素按相反的顺序重新排列。reverse()函数可用于反转各种类型的容器,包括数组、向量、链表等。
以下是一个示例,展示如何使用reverse()函数反转一个整型向量的元素顺序:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int> vec = {1, 2, 3, 4, 5};
reverse(vec.begin(), vec.end());
for(int num : vec) {
cout << num << " ";
}
cout << endl;
// 运行结果
// 5 4 3 2 1
return 0;
}
在上述示例中,std::reverse(vec.begin(),vec.end())将整型向量vec中的元素顺序进行反转。最终输出的结果是5 4 3 2 1。
需要注意的是,reverse()函数只能用于支持双向迭代器的容器,因为它需要能够向前和向后遍历容器中的元素。对于只支持单向迭代的容器(如前向链表),无法使用reverse()函数进行反转。
4. unique()
unique()是一个用于去除容器中相邻重复元素的函数。
它的原型定义在<algorithm>头文件中,函数的声明如下:
template<class ForwardIt>
ForwardIt unique(ForwardIt first, ForwardIt, last);
// 这里的ForwardIt可以理解为迭代器或者地址
unique(first, last)函数接受两个参数:
1.first:指向容器中要去重的第一个元素的迭代器
2.last:指向容器中要去重的最后一个元素的下一个位置的迭代器
unique()函数将[first,last)范围内的相邻重复元素取出,并返回一个指向去重后范围的尾后迭代器,去重后的范围中只保留第一个出现的元素,重复的元素都被移除到最后。注意:并不是直接去重。
unique()函数可用于取出各种类型的容器中相邻重复元素,包括数组、向量、链表等。以下是一个示例,展示如何使用unique()函数去除一个整型向量中的相邻重复元素:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int> vec = {1, 1, 2, 2, 3, 3, 3, 4, 4, 5};
auto it = unique(vec.begin(), vec.end()); // 将重复元素排到最后,并返回第一个重复元素的地址
vec.erase(it, vec.end()); // 去除重复元素
for(int num : vec) {
cout << num << " ";
}
cout << endl;
// 运行结果
// 1 2 3 4 5
return 0;
}
具体过程:
定义vec:
经过unique排序后:
erase删去[it,end)的元素
- 在上述示例中, std:unique(vec.begin(), vec.end())将整型向量vec中的相邻重复元素去除。最终输出的结果是12345。
- 需要注意的是, unique()函数只能去除相邻的重复元素,如果容器中存在非相邻的重复元素,则无法去除。
- 如果需要去除所有重复元素,而不仅仅是相邻的重复元素,可以先对容器进行排序、然后再使用unique()函数。
- unique()时间复杂度为 O ( n ) O(n) O(n),但一般需要先用sort函数进行排序( O ( n l o g n ) O(nlogn) O(nlogn)),会导致时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)
, unique()函数只能去除相邻的重复元素,如果容器中存在非相邻的重复元素,则无法去除。
- 如果需要去除所有重复元素,而不仅仅是相邻的重复元素,可以先对容器进行排序、然后再使用unique()函数。
- unique()时间复杂度为 O ( n ) O(n) O(n),但一般需要先用sort函数进行排序( O ( n l o g n ) O(nlogn) O(nlogn)),会导致时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)