用哈希表去除数据中的重复项
哈希表(Hash Table,也叫散列表),是根据键(Key)而直接访问在内存存储位置的数据结构。哈希表通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做哈希函数,存放记录的数组称做哈希表。
1.unordered_set构造函数
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初始化
unordered_set常用函数
set1.find(2); //查找2,找到返回迭代器,失败返回end()
set1.count(2); //返回指2出现的次数,0或1
set1.emplace(3); //使用转换移动构造函数,返回pair<unordered_set<int>::iterator, bool>
set1.insert(3); //插入元素,返回pair<unordered_set<int>::iterator, bool>
set1.insert({1,2,3}); //使用initializer_list插入元素
set1.insert(set1.end(), 4);//指定插入位置,如果位置正确会减少插入时间,返回指向插入元素的迭代器
set1.insert(set2.begin(), set2.end());//使用范围迭代器插入
set1.erase(1); //删除操作,成功返回1,失败返回0
set1.erase(set1.find(1)); //删除操作,成功返回下一个pair的迭代器
set1.erase(set1.begin(), set1.end()); //删除set1的所有元素,返回指向end的迭代器
set1.empty(); //是否为空
set1.size(); //大小
set1.bucket_count(); //返回容器中的桶数
set1.bucket_size(1); //返回1号桶中的元素数
set1.bucket(1); //1在哪一个桶
set1.load_factor(); //负载因子,返回每个桶元素的平均数,即size/float(bucket_count);
set1.max_load_factor();//返回最大负载因子
set1.max_load_factor(2);//设置最大负载因子为2,rehash(0)表示强制rehash
set1.rehash(20);//设置桶的数量为20,并且重新rehash
set1.reserve(20);//将容器中的桶数设置为最适合元素个数,如果20大于当前的bucket_count乘max_load_factor,则增加容器的bucket_count并强制重新哈希。如果20小于该值,则该功能可能无效。
unordered_set<int>::iterator it = set1.begin(); //返回指向set1首元素的迭代器
unordered_set<int>::const_iterator c_it = set1.cbegin(); //返回指向set1首元素的常量迭代器
unordered_set<int>::local_iterator it = set1.begin(1);//返回1号桶中的首元素迭代器
unordered_set<int>::const_local_iterator c_it = set1.cbegin(1);//返回1号桶中的首元素的常量迭代器
pair<unordered_set<int>::iterator, unordered_set<int>::iterator> it = set1.equal_range(1);//返回一个pair,pair里面第一个变量是lower_bound返回的迭代器,第二个迭代器是upper_bound返回的迭代器
set1.clear(); //清空
3.验证插入元素是否重复
由于unordered_set底层实现为hash,故set内不会出现重复元素。根据这个性质,结合insert函数,可以验证插入元素是否重复。
#include<iostream>
#include<unordered_set>
using namespace std;
#define NUMS 9
int main(){
int testdata[NUMS]={1,2,1,4,5,4,3,3,3};
unordered_set<int> hash;
for(int i=0;i<=NUMS;i++){
if(hash.find(testdata[i])!=hash.end()){
cout<<"有重复值!"<<endl;
break;
}
hash.insert(testdata[i]);
}
return 0;
}
4.哈希表去除数据重复项
示例有21条数据,现要求将两个数字都重复的行,只保留一个,由于是要同时判断两个关键字,因此定义了pair_hash结构体,数据文件如下:
代码如下:
#include <iostream>
#include <vector>
#include <unordered_set>
#include<iostream>
#include<fstream>
using namespace std;
//自定义哈希函数,元素类型为 pair<T1, T2> a(X1, X2);
struct pair_hash
{
template <class T1, class T2>
size_t operator () (pair<T1, T2> const& pair) const
{
size_t h1 = hash<T1>()(pair.first); //用默认的 hash 处理 pair 中的第一个数据 X1
size_t h2 = hash<T2>()(pair.second);//用默认的 hash 处理 pair 中的第二个数据 X2
return h1 ^ h2;
}
};
int main() {
ifstream f("Testdata.txt");
int nums;
f >> nums;
int index;
double *x=new double[nums];
double *y = new double[nums];
for (int i = 0; i < nums; i++) {
f >> index >> x[i] >> y[i];
}
f.close()
unordered_set<pair<double,double>,pair_hash> hash;
for (int i = 0; i < nums; i++) {
hash.insert({x[i],y[i]});
}
printf("%d\n",hash.size());
for (auto p : hash) {
cout << p.first << " " << p.second << endl;
}
return 0;
}
运行结果结果如下:
5.参考链接
1.https://blog.csdn.net/waveleting/article/details/109002440
2.https://www.cnblogs.com/Kissfly123/p/14637969.html