毫秒查询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 ...
随机推荐
- Django模板层
一:模板简介 二:模板语法值变量 三: 模板之过滤器 四: 模板之标签 五:自定义标签和过滤器 一:模板简介 def current_datetime(request): now=datetime ...
- 常见gcc编译问题解决方法集
除非明确说明,本文内容仅针对x86/x86_64的Linux开发环境,有朋友说baidu不到,开个贴记录一下(加粗字体是关键词):用"-Wl,-Bstatic"指定链接静态库,使用 ...
- eclipse 高效快捷键大全
一个Eclipse骨灰级开发者总结了他认为最有用但又不太为人所知的快捷键组合.通过这些组合可以更加容易的浏览源代码,使得整体的开发效率和质量得到提升. 1. ctrl+shift+r:打开资源 这可能 ...
- Mahout学习资料
Apache Mahout 简介 http://www.ibm.com/developerworks/cn/java/j-mahout/ 从源代码剖析Mahout推荐引擎 http://blog.fe ...
- Mathout In Action(中文)
http://download.csdn.net/detail/zxnm55/5593881
- linux bash变量替换(# ## % %% / //)
VAR=hahaha echo ${VAR#*h} # ahaha 从前向后匹配删除 VAR=hahaha echo ${VAR##*h} # a 贪婪模式,从前向后匹配删除所有 VAR=hahaha ...
- Easy前端正确删除datagrid的方式(避免直接删除索引没更新问题)
在删除传参时,不要传索引来删除行 columns: [[ { title: '代码', field: 'Code', width: 100 }, { title: '名称', field: 'Name ...
- c# 多线程线程池基础
线程池的作用 在上一篇中我们了解了创建和销毁线程是一个昂贵的操作,要耗费大量的时间,太多的线程会浪费内存资源,当线程数量操作计算机CPU的数量后操作系统必须调度可运行的线程并执行上下文切 ...
- java public class和class的区别
- 1270: Wooden Sticks [贪心]
点击打开链接 1270: Wooden Sticks [贪心] 时间限制: 1 Sec 内存限制: 128 MB 提交: 31 解决: 11 统计 题目描述 Lialosiu要制作木棍,给n根作为原料 ...