最近在菜鸟教程上自学redis。看到Redis HyperLogLog的时候,对“基数”以及其它一些没接触过(或者是忘了)的东西产生了好奇。

  于是就去搜了“HyperLogLog”,从而引出了Cardinality Estimation算法,以及学习它时参考的一些文章:

  http://blog.codinglabs.org/articles/algorithms-for-cardinality-estimation-part-i.html

  从文章上看来,基数是指一个集合(这里的集合允许存在重复元素,与集合论对集合严格的定义略有不同,如不做特殊说明,本文中提到的集合均允许存在重复元素)中不同元素的个数。

  这就类似“求一个数组中不重复元素的个数”的算法。如数组a[10] = {1,2,3,4,1,2,3,4,5,6,7},那么不重复元素就是{1,2,3,4,5,6,7},一共7个。对于它的应用场景,比如一个网站要统计“一个人”的访问次数的时候,比如小明,那么就给对“小明”打上标记,当它下次来访问的时候,总访问次数不能加一。只有当不是“小明”的人,比如“小丽”来访问,对将总访问次数加一。

  这又好像之前做过的一题算法题:统计字符串“abcdaaabceeda”中不重复的字母的个数了。当然,最简单粗爆的方法就是去一次又一次地遍历,如:判断第n个字符是否有出现过,先对前n-1个字符进行遍历比较。这样的话也太浪费时间了。于是,当时我想了一个办法:字符串中只有字母,只要建一个长度为26的哈希表,然后遍历一次字符串,把读到的字符填进哈希表中,最后遍历哈希表就可以了:

hash.c

 #include <stdio.h>
#include <string.h> int main()
{
char str[] = "abcdaaabceeda";
int hash[] = {};
int size = strlen(str);
int i;
for(i = ; i < size; ++i)
{
int temp = str[i] - 'a';
++hash[temp];
}
int num = ;
for(i = ; i < ; ++i)
{
num += hash[i] > ? : ;
}
printf("num = %d\n", num);
}

  如果只统计26个小写字母,只需要26个int型空间。想到bitmap可以节约空间,于是也用它写了一个:

bitmap.c

 #include <stdio.h>
#include <string.h> int hamming_weight(unsigned int bitmap)
{
unsigned int temp = bitmap;
temp = (temp & 0x55555555) + ((temp & 0xaaaaaaaa) >> );
temp = (temp & 0x33333333) + ((temp & 0xcccccccc) >> );
temp = (temp & 0x0f0f0f0f) + ((temp & 0xf0f0f0f0) >> );
temp = (temp & 0x00ff00ff) + ((temp & 0xff00ff00) >> );
temp = (temp & 0x0000ffff) + ((temp & 0xffff0000) >> );
return temp;
} int main()
{
char str[] = "abcdaaabceeda";
unsigned int bitmap = ;
int size = strlen(str);
int i;
for(i = ; i < size; ++i)
{
int loc = str[i] - 'a';
int temp = << loc;
bitmap |= temp;
}
printf("num = %d\n", hamming_weight(bitmap));
}

  区别就是用hash还可以统计单个字符出现的次数,而bitmap可以用到hamming weight来统计总次数,且节省了大量空间。

  对于网站统计“小明”等人的访问次数的问题,其实相当于要把“小明”传入哈希函数,然后找到相应地址,标记为“已访问”。要统计的时候,根据哈希表的数据结构进行遍历,或是计算bitmap中1的个数等方法来统计。以上是我的个人见解,不涉及概率等实现问题。

Cardinality Estimation算法学习(一)(了解基数计算的基本概念及回顾求字符串中不重复元素的个数的问题)的更多相关文章

  1. 萌新笔记——Cardinality Estimation算法学习(一)(了解基数计算的基本概念及回顾求字符串中不重复元素的个数的问题)

    最近在菜鸟教程上自学redis.看到Redis HyperLogLog的时候,对"基数"以及其它一些没接触过(或者是忘了)的东西产生了好奇. 于是就去搜了"HyperLo ...

  2. 萌新笔记——Cardinality Estimation算法学习(二)(Linear Counting算法、最大似然估计(MLE))

    在上篇,我了解了基数的基本概念,现在进入Linear Counting算法的学习. 理解颇浅,还请大神指点! http://blog.codinglabs.org/articles/algorithm ...

  3. Cardinality Estimation算法学习(二)(Linear Counting算法、最大似然估计(MLE))

    在上篇,我了解了基数的基本概念,现在进入Linear Counting算法的学习. 理解颇浅,还请大神指点! http://blog.codinglabs.org/articles/algorithm ...

  4. 算法练习之x的平方根,爬楼梯,删除排序链表中的重复元素, 合并两个有序数组

    1.x的平方根 java (1)直接使用函数 class Solution { public int mySqrt(int x) { int rs = 0; rs = (int)Math.sqrt(x ...

  5. 我的Java开发学习之旅------>求字符串中出现次数最多的字符串以及出现的次数

    金山公司面试题:一个字符串中可能包含a~z中的多个字符,如有重复,如String data="aavzcadfdsfsdhshgWasdfasdf",求出现次数最多的那个字母及次数 ...

  6. python经典算法题:求字符串中最长的回文子串

    题目 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab" 注意: ...

  7. 【Java学习笔记】<集合框架>定义功能去除ArrayList中的重复元素

    import java.util.ArrayList; import java.util.Iterator; import cn.itcast.p1.bean.Person; public class ...

  8. 写出一个程序,接受一个由字母和数字组成的字符串,和一个字符,然后输出输入字符串中含有该字符的个数。不区分大小写。java算法

    知识点一:equalsIgnore 1.使用equals( )方法比较两个字符串是否相等.它具有如下的一般形式: boolean equals(Object str) 这里str是一个用来与调用字符串 ...

  9. Java入门:基础算法之从字符串中找到重复的字符

    本程序演示从一个字符串中找出重复的字符,并显示重复字符的个数. import java.util.HashMap; import java.util.Map; import java.util.Set ...

随机推荐

  1. java类型与jdbc类型对应表

      java.sql.Types 值 Java 类型 IBM DB2 Oracle Sybase SQL Informix IBM Content Manager   BIGINT java.lang ...

  2. PHP中SimpleXMLElement对象字符编码

    最近在使用SimpleXMLElement来生成和解析XML. 由于我们使用PHP开发的这边使用UTF-8编码,而对方使用GBK编码,因此就遇到了中文字符编码问题. 后来发现,XML内部的编码与其头 ...

  3. docker搭建elk+cerebro环境

    ELK的帮助手册 Docker Hub官网:https://hub.docker.com/r/sebp/elk/ Docker ELK使用文档:http://elk-docker.readthedoc ...

  4. 什么是hive

    Hadoop Hive概念学习系列之什么是Hive? 参考  <Hadoop大数据分析与挖掘实战>的在线电子书阅读                   http://yuedu.baidu ...

  5. 用Javac编译Java文件时出现“编码 GBK 的不可映射字符“的error

    前提:JDK版本 >= 1.6会出现编译报错, 1.6前只会是警告 以下是javac的document: 遇到这种情况的原因是: 文件编码格式与编译器编译所选的encoding不同,有非英文字符 ...

  6. ONTAK2010 Peaks加强版(离线&在线)

    题面 弱化版:luogu 强制在线版:bzoj 题解 本题有两种解法 离线算法:线段树合并 先看一道简单题[USACO18JAN]MooTube 本题就是在此基础上求第\(k\)高的点 首先把询问和路 ...

  7. (二)Audio子系统之new AudioRecord()(Android4.4)

    在上一篇文章<(一)Audio子系统之AudioRecord.getMinBufferSize>中已经介绍了AudioRecord如何获取最小缓冲区大小,接下来,继续分析AudioReco ...

  8. D3.js绘制平行坐标图

    参照:https://syntagmatic.github.io/parallel-coordinates/ 和 https://github.com/syntagmatic/parallel-coo ...

  9. MySQL多表更新

    多表更新:参照另外的表来更新本表的内容 table_reference {[inner | cross] join | {left | right} [outer] join}  内连接.左外连接.右 ...

  10. jmeter调试脚本之用户自定义变量

    一.用户自定义的变量 用户自定义变量,设置变量名.变量值,就引用变量名执行操作 名称:用户定义变量的描述性名称,显示在左边节点上,并用于命名事务 注释:用户定义变量的注释信息,非必填项 变量名称:定义 ...