文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

使用BitSet位集合,一个重复校验工具

2022-11-13 19:05

关注

BitSet位集合,一个重复校验工具

BitSet,位集合,用于判断一个int数字是否存在与bitSet中。

使用一个或多个long存储数据,占用内存超级小,因为判断64位二进制long中第n位为1表示n这个数字存在,为0表示不存在。所以一个long可以表示2^63 -1个数字的存在情况。

使用场景,如手机号重复校验,数字id重复校验,QQ号重复校验等大量防重的场景。

存在与否是精确的,说不存在绝对不存在,说存在绝对存在,不像布隆过滤器。

1.bitset的内部实现是long数组,因为一个long位数不够表示时,会扩展到多个long

2.set中每一个位的默认值为false(0)

3.bitset长度按需增长

4.bitset非线程安全

    public static void bitSetDemo() {
        
        BitSet bs = new BitSet(10);
        bs.set(1);
        bs.set(2);
        bs.set(5);
        System.out.println(bs.get(2));//true
        System.out.println(bs.get(1));//true
        System.out.println(bs.get(3));//false,不存在
        System.out.println(bs.get(5));//true
        //返回bitSet中已存入的数量
        System.out.println(bs.cardinality());//3
        //逻辑位数
        System.out.println(bs.length());//6
        //实际位数
        System.out.println(bs.size());//64
        System.out.println(bs.toString());//{1, 2, 5}
        BitSet bs2 = new BitSet();
        bs2.set(1);
        bs2.set(2);
        bs2.set(6);
        System.out.println(bs2.toString());//{1, 2, 6}
        //取交集,两者都有的才保留
        bs.and(bs2);
        System.out.println(bs.toString());//{1, 2}
        //取并集,把两者所有的都保留
        bs.or(bs2);
        System.out.println(bs.toString());//{1, 2, 6}
    }

BitSet的基本用法

概念

bitset可以说是一个多位二进制数,每八位占用一个字节,因为支持基本的位运算,所以可用于状态压缩,n位bitset执行一次位运算的时间复杂度可视为n/32.

基本操作

1.定义:

表示一个n位的二进制数,<>中填写位数;

2.位运算操作符:

3.[ ]操作符:

4.count:

5.any/none

若s所有位都为0,则s.any()返回false,s.none()返回true;

若s至少有一位为1,则s.any()返回true,s.none()返回false;

6.set/rest/flip

题目

可达性统计(AcWing164)

思路:

遍历一遍图,在回溯时将子节点状态加入节点状态中,用一个n长度的二进制bitset串记录状态第i位为1表示i节点从该节点可达,最后输出每个节点状态中1的个数即可。遍历时从入度为1的节点开始.

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll inf=1e9+7;
bitset<30005> s[30005];
vector<int> g[30005];
int in[30005], vis[30005];
queue<int> q;
void dfs(int v)
{
    //printf("v=%d\n",v);
    if(vis[v])
    {
        return ;
    }
    s[v][v]=1;
    for(int i=0;i<g[v].size();i++)
    {
        int u=g[v][i];
        dfs(u);
        s[v]|=s[u];
    }
    vis[v]=1;
}
int main()
{
    int n, m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int u, v;
        scanf("%d%d",&u,&v);
        g[u].push_back(v);
        in[v]++;
    }
    for(int i=1;i<=n;i++)
    {
        if(in[i]==0)
        {
            q.push(i);
        }
    }
    while(!q.empty())
    {
        int v=q.front();
        q.pop();
        dfs(v);
    }
    for(int i=1;i<=n;i++)
    {
        printf("%d\n",s[i].count());
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯