毫秒查询9位数qq号码是否存在-BitMap算法应用
实现详情请查看博客园
https://www.cnblogs.com/caoke/p/10793885.html
随机注册10万个放入BitMap,然后查询qq号码是否已存在,算法复杂度O(1).
//BitMap算法demo,查询9位数字
const b=new BitMap('[0~9][0~9][0~9][0~9][0~9][0~9][0~9][0~9][0~9]') //设置
console.time('设置时间')
for(let i=0;i<b.length;i=i+1000){
b.set(b.toString(i));
i=0|Math.random()*1000+i;
}
// b.set('123456783')
// b.set('123456783')
// b.set('223456783')
b.set('323456783')
console.timeEnd('设置时间') console.time('查询时间')
console.log(b.has('123456783'))
console.log(b.has('433456783'))
console.log(b.has('243456783'))
console.log(b.has('453456783'))
console.log(b.has('323456783'))
console.log(b.has('423456783'))
console.timeEnd('查询时间')
/usr/local/bin/node /Users/caoke/go/bitmap.js
设置时间: 3212.917ms
false
false
false
false
true
false
查询时间: 0.629ms
Process finished with exit code 0
源码
/*
* ckHash函数类,将字符串映射成数字,同时可以将数字映射成字符串,
* 用于数据压缩,加密解密,以及bitMap大数据查询,去重
* 作者:caoke
* */ class ckHash{
//输入密钥
constructor(secretKey){
this.secretKey=secretKey; this.regexp=new RegExp(secretKey.replace(/\[([^\[]+?)\]/g,function (m) {
return '('+m.replace(/-/g,'\\-').replace(/~/g,'-')+')'
}).replace(/[\\\^\:\.\?\+]/g,'\\$&')); this.lenArr=[];
this.dataArr=[];
secretKey.replace(/\[([^\[]+?)\]/g,(m,p1)=>{
const arr=[];
for(let i=0;i<p1.length;i++){
if(p1[i]==='~'){
arr.push('~')
}else{
arr.push(p1[i].charCodeAt(0));
}
}
let length=0;
for(let i=0;i<arr.length;i++){
if(arr[i]==='~'){
length=length+arr[i+1]-arr[i-1];
i++;
}else{
length=length+1;
}
}
this.lenArr.push(length)
this.dataArr.push(arr)
})
this.length=this.lenArr.reduce((x,y)=>x*y)
}
//将数字映射成字符串
toString(number){
const arr=[];
for(let i=this.lenArr.length-1;i>0;i--){
const n1=number%this.lenArr[i];
arr.unshift(n1)
number=Math.floor(number/this.lenArr[i]);
}
arr.unshift(number) const codeArr=[]
for(let i=0;i<arr.length;i++){
const dataArr=this.dataArr[i];
let len= arr[i]; let code;
for(let j=0;j<dataArr.length;j++){
if(dataArr[j]==='~'){
if(len<dataArr[j+1]-dataArr[j-1]){
code=dataArr[j-1]+len+1;
break;
}else{
len=len-(dataArr[j+1]-dataArr[j-1]);
j++;
}
}else if(len===0){
code=dataArr[j]
break;
}else{
len--;
}
}
codeArr.push(String.fromCharCode(code))
}
let index=0;
return this.secretKey.replace(/\[([^\[]+?)\]/g,(m,p1)=>{
return codeArr[index++];
})
}
//将字符串映射成数字
toNumber(string){
if(this.regexp.test(string)){
const arr=[]
string.replace(this.regexp,function (m,p1) {
for(let i=1;i<arguments.length-2;i++){
arr.push(arguments[i].charCodeAt(0))
}
}); const lenArr=[]
for(let i=0;i<arr.length;i++){
const dataArr=this.dataArr[i];
let len= 0;
for(let j=0;j<dataArr.length;j++){
if(dataArr[j]===arr[i]){
break;
}else if(dataArr[j]==='~'){
if(arr[i]<=dataArr[j+1]&&arr[i]>dataArr[j-1]){
len=len+arr[i]-dataArr[j-1]-1;
break;
}else{
len=len+dataArr[j+1]-dataArr[j-1];
j++;
}
}else{
len++;
}
}
lenArr.push(len)
}
let number=0;
let jz=1;
for(let i=lenArr.length-1;i>=0;i--){
number=number+jz*lenArr[i];
jz=jz*this.lenArr[i]
} return number; }else{
throw string +' 不在匹配范围内';
}
}
} //BitMap算法,大数据查询,算法复杂度O(1)
class BitMap {
constructor(secretKey){
this.hashFunc=new ckHash(secretKey);
this.length=this.hashFunc.length
this.buffer=Buffer.alloc(this.length);
}
has(num){
if(typeof num ==='string'){
num=this.toNumber(num);
}
const n=num>>3;
const k=num%8;
return (this.buffer[n]&1<<k)!==0
}
toString(num){
return this.hashFunc.toString(num);
}
toNumber(str){
return this.hashFunc.toNumber(str);
}
set(num){
if(typeof num ==='string'){
num=this.toNumber(num);
}
const n=num>>3;
const k=num%8;
this.buffer[n]=this.buffer[n]|(1<<k);
}
del(num){
if(typeof num ==='string'){
num=this.toNumber(num);
}
const n=num>>3;
const k=num%8;
this.buffer[n]=this.buffer[n]&~(1<<k);
}
}
毫秒查询9位数qq号码是否存在-BitMap算法应用的更多相关文章
- 找女神要QQ号码
引言 我们组来了个美女程序员,我心里窃喜,哈哈这下机会来了.我在想怎么下手呢?好吧,还是从QQ号码开始,找到女神要到QQ号,哈哈,我真是个天才~~~ 是这样子滴 想法是美好的,现实是残酷的,找女神要Q ...
- JS获得QQ号码的昵称,头像,生日
这篇文章主要介绍了JS获得QQ号码的昵称,头像,生日的简单实例,有需要的朋友可以参考一下 http://r.qzone.qq.com/cgi-bin/user/cgi_personal_card?ui ...
- “找女神要QQ号码”——java篇
题目就是这样的: 给了一串数字(不是QQ号码),根据下面规则可以找出QQ号码: 首先删除第一个数,紧接着将第二个数放到这串数字的末尾,再将第三个数删除,并将第四个数放到这串数字的末尾...... 如此 ...
- 用JS获得QQ号码的昵称,头像,生日
有一个网址,可以返回我们要的内容. http://r.qzone.qq.com/cgi-bin/user/cgi_personal_card?uin=指定QQ号码 将会返回下列内容: _Callbac ...
- js正则表达式:验证邮箱格式、密码复杂度、手机号码、QQ号码
直接上代码 Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ...
- 美女程序员是如何将QQ转换成题目中那串数字的--读博文《找女神要QQ号码》
我只能说好好的端午节你们不约么?,还在这里写代码?我也是够无聊的,下班了不走也在这跟风写着玩!<找女生要QQ号码原文>原文链接http://www.cnblogs.com/iforever ...
- YII 验证邮箱和QQ号码
//验证邮箱非空,和邮箱格式 //验证邮箱非空,和邮箱格式 array("email","e ...
- Java基础知识强化70:正则表达式之引入案例(QQ号码校验)
1. 校验QQ号码的案例,如下: package cn.itcast_01; import java.util.Scanner; /* * 校验qq号码. * 1:要求必须是5-15位数字 * 2:0 ...
- destoon程序中qq号码,手机号,msn必选项实现方法
最近发现好多客户,信息不完全!还是把qq号码,手机号,msn设为必选项比较好!下面以把qq设为必选项为例找到模板 template/default/member/edit.htm 找到 functio ...
随机推荐
- mongodb的安装与启动(centos7)
公司迁移mongodb,查了半天资料,各种考证,各种资讯,最后我选择很野蛮的直接把库和日志直接scp过来了....... 记录下如何安装和启动mongodb: 1.解压mongodb: [root@i ...
- CentOS 最新版的下载地址 + 版本选择详解
CentOS 最新版的下载地址 + 版本选择详解 发现越来越多的机关单位.事业单位开始使用 Linux 作为主要服务器,毕竟,Linux的稳定性和高效性是众所周知的,所以我也打算把自己这一块技术加强一 ...
- POJ 2778 DNA Sequence (AC自动机+DP+矩阵)
题意:给定一些串,然后让你构造出一个长度为 m 的串,并且不包含以上串,问你有多少个. 析:很明显,如果 m 小的话 ,直接可以用DP来解决,但是 m 太大了,我们可以认为是在AC自动机图中,根据离散 ...
- 递归,回溯和DFS的区别
递归是一种算法结构,回溯是一种算法思想一个递归就是在函数中调用函数本身来解决问题回溯就是通过不同的尝试来生成问题的解,有点类似于穷举,但是和穷举不同的是回溯会“剪枝”,意思就是对已经知道错误的结果没必 ...
- Python WebDriver 文件上传(二)
今天补充一种文件上传的方法 主要是因为工作中使用SendKeys方法不稳定,具体方法见: Python WebDriver 文件上传(一) 这种方法直接通过命令行执行脚本时没有问题,可以成功上传,但是 ...
- [label][Node.js] Three content management systems base on Node.js
1. Keystonejs http://keystonejs.com/ 2. Apostrophe http://apostrophenow.org/
- Java反射API研究(1)——注解Annotation
注解在表面上的意思,只是标记一下这一部分,最好的注解就是代码自身.而在java上,由于注解的特殊性,可以通过反射API获取,这种特性使得注解被广泛应用于各大框架,用于配置内容,代替xml文件配置. 要 ...
- 记录一下显示Map<String, ArrayList<String>>中的ArrayList里的数据的操作
1.有以下数据: ArrayList<Employee> emp = new ArrayList<>(); emp.add(new Employee("zhang&q ...
- ASP.NET基于NPOI导出数据
using System; using System.Collections; using System.Collections.Generic; using System.IO; using Sys ...
- Amazon新一代云端关系数据库Aurora(下)
本文由 网易云发布. 作者:郭忆 本篇文章仅限内部分享,如需转载,请联系网易获取授权. 故障恢复 MySQL基于Check point的机制,周期性的建立redo log与数据页的一致点.一旦数据库 ...