- vector去重
第一种,利用set容器的特性进行去重:
cpp
#include <iostream>
#include <vector>
#include <set>
using namespace std;
int main() {
vector<int>test={1,2,3,3,3,4,2,3,5,2,63,56,34,24};
set<int>s(test.begin(), test.end());//set会自动进行排序。
test.assign(s.begin(), s.end());//assign() 函数将区间[start, end)的元素赋到当前vector,
//或者赋num个值为val的元素到vector中.这个函数将会清除掉vector以前的内容.
//可以用于不同容器之间的赋值。
for(int x : test)
cout << x <<" ";
return 0;
}
第二种方法:利用unique函数进行处理:
unique()函数将相邻且重复的元素放到vector的尾部
然后返回指向第一个重复元素的迭代器再用erase函数擦除从这个元素到最后元素的所有的元素。
cpp
#include <iostream>
#include <vector>
#include <set>
using namespace std;
int main() {
vector<int>test={1,2,3,3,3,4,2,3,5,2,63,56,34,24};
sort(test.begin(),test.end());
test.erase(unique(test.begin(),test.end()),test.end());
for(int x:test)
cout<<x<<" ";
return 0;
}
- set
set作为一个容器也是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。应该注意的是set中数元素的值不能直接被改变。C++ STL中标准关联容器set, multiset, map, multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树,所以被STL选择作为了关联容器的内部结构。
cpp
begin() ,返回set容器的第一个迭代器
end() ,返回set容器的最后一个迭代器
clear() ,删除set容器中的所有的元素
empty() ,判断set容器是否为空
max_size() ,返回set容器可能包含的元素最大个数
size() ,返回当前set容器中的元素个数
rbegin() ,返回的值和end()相同
rend() ,返回的值和rbegin()相同
- find()函数
C++中的find()函数有多种用法。它可以用于string类,用于查找字符或字符串。查找成功则返回第一个字符或者字串的位置,查找失败则返回string::npos即为-1。此外,find()也可以用于vector容器,用于查询指定元素是否存在。还有一个STL函数find(),它位于头文件下,返回一个迭代器,指向范围内搜索元素的第一次出现。
(1)string类的find 函数和<algorithm>头文件下的find函数的区别
string类的find()函数用于在字符串中查找字符或子串,返回第一个匹配的位置。而<algorithm>头文件下的find()函数是一个通用的算法,它可以在任何容器中查找指定元素,返回一个迭代器指向第一个匹配的元素。
这两个函数的主要区别在于它们所作用的对象不同。string类的find()函数只能用于字符串,而<algorithm>头文件下的find()函数可以用于任何容器。
cpp
#include <algorithm>
#include <vector>
#include <iostream>
int main()
{
std::vector<int> v = {1, 2, 3, 4, 5};
auto it = std::find(v.begin(), v.end(), 3);
if (it != v.end())
std::cout << "Element found: " << *it << '\n';
else
std::cout << "Element not found\n";
}
//上面的代码会在控制台输出"Element found: 3"。
- STL的优先队列(priority_queue)
优先队列的本质是堆,但它具有队列的所有操作特性,与普通队列不同的地方就是出队的时候按照优先级顺序出队,这个优先级即最大堆或最小堆的规则(即大的为top优先出队或小的为top优先出队),在队列的基础上加了个堆排序。
以O(logn) 的效率查找一个队列中的最大值或者最小值,其中是最大值还是最小值是根据创建的优先队列的性质来决定的。
作为队列的一个延伸,优先队列包含在头文件#include < queue >
中。
语法
cpp
priority_queue<Type, Container, Functional>
其中Type 为数据类型, Container 为保存数据的容器,Functional 为元素比较方式。
在STL中,默认情况下(不加后面两个参数)是以vector为容器,以 operator< 为比较方式,所以在只使用第一个参数时,优先队列默认是一个最大堆 ,每次输出的堆顶元素是此时堆中的最大元素。
用到最小堆,则一般要把模板的三个参数都带进去。
STL里面定义了一个仿函数 greater<>,对于基本类型可以用这个仿函数声明最小堆(升序)
cpp
//构造一个空的优先队列(此优先队列默认为大顶堆)
priority_queue big_heap;
//另一种构建大顶堆的方法
priority_queue<int, vector<int>, less<int> > c;
//构造一个空的优先队列,此优先队列是一个小顶堆
priority_queue<int, vector<int>, greater<int> > c;
//需要注意的是,如果使用less和greater,需要头文件:
#include <functional>
//成员函数
push() 它将新元素插入优先队列。
pop() 它将优先级最高的元素从队列中删除。
top() 此函数用于寻址优先队列的最顶层元素。
size() 返回优先队列的大小。
empty() 它验证队列是否为空。基于验证,它返回队列的状态。
swap() 它将优先队列的元素与具有相同类型和大小的另一个队列交换。
emplace() 它在优先队列的顶部插入一个新元素。
-
rand() 函数
rand()不需要参数,它会返回一个从0到最大随机数的任意整数,最大随机数的大小通常是固定的一个大整数。
如果你要产生0~ 99这100个整数中的一个随机整数,可以表达为:int num = rand() % 100; 这样,num的值就是一个0~99中的一个随机数了。
总结来说,可以表示为:int num = rand() % n +a; 其中的a是起始值,n是整数的范围,n+a-1是终止值。
-
unordered_set
C++ 11中出现了两种新的关联容器:unordered_set和unordered_map,其内部实现与set和map大有不同,set和map内部实现是基于RB-Tree,而unordered_set和unordered_map内部实现是基于哈希表(hashtable),由于unordered_set和unordered_map内部实现的公共接口大致相同.
cpp
//构造函数
unordered_set<int> set1; //创建空set
unordered_set<int> set2(set1); //拷贝构造
unordered_set<int> set3(set1.begin(), set1.end()); //迭代器构造
unordered_set<int> set4(arr,arr+5); //数组构造
unordered_set<int> set5(move(set2)); //移动构造
unordered_set<int> set6 {1,2,10,10};//使用initializer_list初始化
//基本操作
begin() 返回指向容器中第一个元素的正向迭代器。
end(); 返回指向容器中最后一个元素之后位置的正向迭代器。
cbegin() 和 begin() 功能相同,只不过其返回的是 const 类型的正向迭代器。
cend() 和 end() 功能相同,只不过其返回的是 const 类型的正向迭代器。
empty() 若容器为空,则返回 true;否则 false。
size() 返回当前容器中存有元素的个数。
max_size() 返回容器所能容纳元素的最大个数,不同的操作系统,其返回值亦不相同。
find(key) 查找以值为 key 的元素,如果找到,则返回一个指向该元素的正向迭代器;反之,则返回一个指向容器中最后一个元素之后位置的迭代器(如果 end() 方法返回的迭代器)。
count(key) 在容器中查找值为 key 的元素的个数。
equal_range(key) 返回一个 pair 对象,其包含 2 个迭代器,用于表明当前容器中值为 key 的元素所在的范围。
emplace() 向容器中添加新元素,效率比 insert() 方法高。
emplace_hint() 向容器中添加新元素,效率比 insert() 方法高。
insert() 向容器中添加新元素。
erase() 删除指定元素。
clear() 清空容器,即删除容器中存储的所有元素。
swap() 交换 2 个 unordered_map 容器存储的元素,前提是必须保证这 2 个容器的类型完全相等。
bucket_count() 返回当前容器底层存储元素时,使用桶(一个线性链表代表一个桶)的数量。
max_bucket_count() 返回当前系统中,unordered_map 容器底层最多可以使用多少桶。
bucket_size(n) 返回第 n 个桶中存储元素的数量。
bucket(key) 返回值为 key 的元素所在桶的编号。
load_factor() 返回 unordered_map 容器中当前的负载因子。负载因子,指的是的当前容器中存储元素的数量(size())和使用桶数(bucket_count())的比值,即 load_factor() = size() / bucket_count()。
max_load_factor() 返回或者设置当前 unordered_map 容器的负载因子。
rehash(n) 将当前容器底层使用桶的数量设置为 n。
reserve() 将存储桶的数量(也就是 bucket_count() 方法的返回值)设置为至少容纳count个元(不超过最大负载因子)所需的数量,并重新整理容器。
hash_function() 返回当前容器使用的哈希函数对象。
- 类的定义和声明
cpp
class/struct 类名 //类头
{数据和方法的定义(可能含有类型成员)}; //类体
- 使用class和struct的唯一区别是:使用class定义的类在没有被强制限定的话,其成员时私有的,即不能被外部调用。使用struct的话,其成员是公共的,可以被外部调用。
- 每个类定义了唯一的类型,即使两个类的成员完全一样,只要类名不同,它们也是不同类型。
- 类体中的数据描述的是类的特征(属性),方法是类中定义的函数,描述类的行为。类型成员用于在类的作用域中指定类型的别名。
访问修饰符
public:表示类的成员可以被外部访问;
private:表示类的成员不可以被外部访问。
cpp
class Object
{
public:
int a;
int b;
void Test()
{
printf("Hello, i am test.\n");
}
private:
double c;
};
int main()
{
Object a;
a.a = 1;
a.b = 2;
a.Test();
Object* b = &a;
printf("%d \n", b->a);
std::cout << "Hello World!\n";
return 0;
}
this指针
其实就是为了方便,不然你要手动传对象指针,比较人性化点。
cpp
#include "stdio.h"
class Object
{
private:
int a;
int b;
//传统C语言方式,传一个指针进去
public:
void Set_value(int a, int b)
{
this->a = a;
this->b = b;
}
int Add()
{
return this->a + this->b;
}
//C++直接就在类内部实现了这个功能
void Test_add()
{
printf("Add:%d \n", this->Add());
}
void Print_this()
{
printf("this:%p\n", this); //打印this地址
}
};
int main()
{
Object a;
printf("a:%p\n", &a);//打印对象地址
a.Print_this();
a.Set_value(2, 6); //设置值
a.Test_add(); //加法并打印
std::cout << "Hello World!\n";
return 0;
}