当前位置: 首页 > news >正文

【算法】大数据查重

大数据查重

哈希表

找出第一个出现重复的数字 || 找所有重复出现的数字

#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <stdlib.h>
#include <time.h>
#include <string>
using namespace std;

#if 0
int main()
{
    vector<int> vec;
    srand(time(NULL));
    for(int i = 0; i < 10000; i++)
    {
        vec.push_back(rand() % 10000);
    }
    // 找出第一个出现重复的数字 || 找所有重复出现的数字
    unordered_set<int> s1;
    for(auto key : vec)
    {
        auto it = s1.find(key);
        if(it == s1.end())
        {
            s1.insert(key);
        }
        else
        {
            cout << "key:" << key << endl;
            break;
        }
    }

    统计重复数字以及出现的次数
    unordered_map<int, int> m1;
    for(auto key : vec)
    {
        auto it = m1.find(key);
        if( it == m1.end())
        {
            m1.emplace(key, 1);
        }
        else
        {
            it->second += 1;
        }
    }
    for(auto pair : m1)
    {
        if(pair.second > 1)
        {
            cout << "key:" << pair.first << "cnt:" << pair.second << endl;
        }
    }

    // 一组数据有些数据是重复的,把重复的数据过滤掉
    unordered_set<int> s2;
    for(auto key : s2)
    {
        s2.emplace(key);
    }


    return 0;
}

问题描述:有两个文件a和b,里面放了ip地址(URL,email)找出两个文件重复的ip,小于100M

分治思想,把大文件分成小文件,1-10,然后分别查重

位图算法

        位图法:就是用一个位(0或者1)来存储数据的状态,比较适合状态简单,数据量比较大,要求内存使用率低的问题场景。位图法解决问题,首先需要知道待处理数据中的最大值,然后按照size=(maxNumber/32)+1的大小来开辟一个char类型的数组,当需要在位图中查找某个元素是否存在时,首先需要计算该数字对应的数组中的比特位,然后读取值,0表示不存在,1表示已存在。

 

题目描述:有一亿个整数,最大不超过一亿,问哪些元素重复了,谁是第一个重复的,内存限制100M

        char数组就是8位,short就是16位,int就是32位

如何获取该位的值?

        bitmap[index] & (1 << offset) 就是1左移offset位,然后和bitmap[index]相与&,00000000 & 10000000 结果就是00000000,即就是没出现过

如何把这个位置置成1?

        即就是bitmap[index] | (1 << offset),10000000 | 00000000 = 10000000

int main()
{
    vector<int> vec = {12, 78, 90, 12, 8, 9};

    // 定义位图数组
    int max = vec[0];
    for (int i = 1; i < vec.size(); i++)
    {
        if (vec[i] > max)
        {
            max = vec[i];
        }
    }

    cout << max << endl;

    int *bitmap = new int[max / 32 + 1]();
    unique_ptr<int> ptr(bitmap);

    for (auto key : vec)
    {
        int index = key / 32;
        int offset = key % 32;

        if (0 == (bitmap[index] & (1 << offset)))
        {
            bitmap[index] |= (1 << offset);
        }
        else
        {
            cout << key << "key是第一个重复出现的数字。" << endl;
            return 0;
        }
    }

    return 0;
}

布隆过滤器

布隆过滤器是一种更高级的“位图法”解决方法,之所以它更高级,是因为他没有上面位图法所说的缺陷。

1.Bloom Filter是通过一个位数组和k个哈希函数构成的。

2.Bloom Filter的空间和时间利用率都很高,但它有一定的错误率,虽然错误率很低,他判断一个元素不在一个集合中,那么它一定不在,它判断某个元素在一个集合中,那么该元素可能在,也可能不在。

3.Bloom Filter的查找错误率,当然和位数组大小以及哈希函数的个数有关,具体的错误率计算有相应公式。

4.Bloom Filter默认只支持add和query操作,不支持delete操作(因为存储的状态为有可能也是其他数据的状态为,删除后导致其他元素查找判断出错)

场景一:提示过滤一些非法的网站,或者钓鱼网站等。

把所有可能怀疑有问题的网站的URL添加到布隆过滤器中https://www.xxx.com查找当前访问的网址URL是否在黑名单中,

如果网址URL不存在,那肯定在白名单中的合法的网址,可以访问;如果存在(有误判率),会进行提示网站有风险,禁止访问。

场景二:redis缓存中的应用

 

        查key到底在不在,而且效率要求高,最好还省内存。

        如果key不再,那么直接去db层mysql里面去查询,如果显示在,那么就在redis里面查,如果出现误判,则继续去mysql中查询。

        setBit(key)

        getBit(key) => key不存在 => DB => 缓存redis => return

        getBit(key) => key存在 => redis中找key

/*
 * @Author: jyx
 * @Date: 2025-03-09 13:35:39
 * @LastEditors: jyx
 * @Description:
 */
#include <iostream>
#include <vector>
#include <string>
using namespace std;

class BloomFilter
{
private:
    /* data */
    int bitSize_;
    vector<int> bitMap_;
public:
    BloomFilter(int bitsize = 1471)
        : bitSize_(bitsize)
    {
        bitMap_.resize(bitSize_ / 32 + 1);
    }
    ~BloomFilter()
    {}
    void setBit(const char* str)
    {
        // 计算k组哈希函数的值
        int idx1 = BKDHash(str) % bitSize_;
        int idx2 = RHash(str) % bitSize_;
        int idx3 = JSHash(str) % bitSize_;

        // 把相应的idx1,idx2,idx3这几个位全部置1
        int index = 0;
        int offset = 0;

        index = idx1 / 32;
        offset = idx1 % 32;
        bitMap_[index] |= ( 1 << offset);

        index = idx2 / 32;
        offset = idx2 % 32;
        bitMap_[index] |= (1 << offset);

        index = idx3 / 32;
        offset = idx3 % 32;
        bitMap_[index] |= (1 << offset);
    }


    bool getBit(const char* str)
    {
        int idx1 = BKDHash(str) % bitSize_;
        int idx2 = RHash(str) % bitSize_;
        int idx3 = JSHash(str) % bitSize_;

        int index = 0;
        int offset = 0;

        index = idx1 / 32;
        offset = idx1 % 32;
        if(0 == (bitMap_[index] = (1 << offset)))
        {
            return false;
        }

        index = idx2 / 32;
        offset = idx2 % 32;
        if (0 == (bitMap_[index] = (1 << offset)))
        {
            return false;
        }

        index = idx3 / 32;
        offset = idx3 % 32;
        if (0 == (bitMap_[index] = (1 << offset)))
        {
            return false;
        }

        return true;
    }

    
};

class BlackList
{
private:
    /* data */
    BloomFilter blackList_;
public:
    BlackList(/* args */)
    {}
    ~BlackList()
    {}
    void add(string url)
    {
        blackList_.setBit(url.c_str());
    }
    bool query(string url)
    {
        return blackList_.getBit(url.c_str());
    }
};



int main()
{
    BlackList list;
    list.add("https://www.baidu.com");
    list.add("https://www.taobao.com");
    list.add("https://www.jingdong.com");
    list.add("https://www.leetcode.com");

    string url = "https://www.jingdong.com";

    list.query(url);
    return 0;
}

相关文章:

  • 庞加莱映射的性质
  • vs code 设置字体颜色
  • 深入了解蓝牙广播与扫描响应
  • Codeforces Round 258 (Div. 2) E. Devu and Flowers 生成函数
  • 四、云原生应用监控-Etcd
  • IMX6ULL的最简单的LED驱动程序
  • 南开提出1Prompt1Story,无需训练,可通过单个连接提示实现一致的文本到图像生成。
  • 掌握Linux基础:从文件链接到Shell命令的全面指南
  • CTF杂项——[WUSTCTF 2020]alison_likes_jojo
  • React:类组件(上)
  • 开发、科研、日常办公工具汇总(持续更新)
  • matlab常见的配图代码实现1
  • SpringBatch之ResultSet.next()
  • PythonWeb开发框架—Flask框架之flask-sqlalchemy、序列化和反序列化使用详解
  • MySQL环境搭建和基本操作
  • 从1G到6G的多址接入技术详解
  • ARM嵌入式低功耗高安全:工业瘦客户机的智慧城市解决方案
  • 字符串相乘——力扣
  • Java 大视界 -- Java 大数据在智能体育赛事运动员表现分析与训练优化中的应用(122)
  • Python实例:PyMuPDF实现PDF翻译,英文翻译为中文,并按段落创建中文PDF
  • 菲律宾华人“钢铁大王”撕票案两主谋落网,部分赎金已被提取
  • 萨洛宁、康托罗夫、长野健……7月夏季音乐节来很多大牌
  • 技术派|台军首次试射“海马斯”火箭炮,如何压制这种武器?
  • 两名游客刻划八达岭长城,被拘5日罚200元
  • 完善劳动关系协商协调机制,《共同保障劳动者合法权益工作指引》发布
  • 一条铺过11年时光的科学红毯,丈量上海科创的“长宽高”