最近在菜鸟教程上自学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. [AIR] 使用操作系统默认应用程序打开文件

    AIR 2.0及以上提供了非常简单易用的API让你使用操作系统所定义的关联应用程序打开文件. 这使得使用AIR开发基于“文件管理器”的应用称为可能 用法如下: var file:File = File ...

  2. 用xpath来爬图

    # xpath语法可参考http://www.w3school.com.cn/xpath/xpath_syntax.asp# 本博客引用于https://zhuanlan.zhihu.com/some ...

  3. Tomcat入门级小白教程

    Tomcat 类似与一个apache的扩展型,属于apache软件基金会的核心项目,属于开源的轻量级Web应用服务器,是开发和调试JSP程序的首选,主要针对Jave语言开发的网页代码进行解析,Tomc ...

  4. executeQueryForObject returned too many results.

    //错误位置: 这个错误出现在持久层与数据库交互时,原因是 queryForObject这个方法封装唯一值,但是给出的sql语句返回了多个值 public int getListCount(SqlMa ...

  5. python常用模块之OS

    os模块偏于文件目录管理 <1>.常用方法 工作目录: os.getcwd() 返回当前工作目录 os.chdir(dir) 更改当前工作目录,相当于cd 目录文件操作: os.mkdir ...

  6. 10分钟教你用VS2017将代码上传到GitHub

    前言 关于微软的Visual Studio系列,真可谓是宇宙最强IDE了.不过,像小编这样的菜鸟级别也用不到几个功能.今天给大家介绍一个比较实用的功能吧,把Visual Studio 2017里面写好 ...

  7. (STM32F4) SysTick理解使用

    關於Cortex System Timer (Systick) 網上隨便google就可以找到許多相關範例. 他就是ARM提供的一個24-bit的下數(count-down)計時器我看大部分應用都是提 ...

  8. 判断H5页面环境是否在小程序的webview中

    用小程序提供的wx.miniProgram.getEnv可以获取环境参数,但是它有个问题就是无法在非微信环境下判断.所以在使用wx.miniProgram.getEnv前得先判断是否在微信环境中. 解 ...

  9. c++primer plus笔记

    > 第六版 操作符重载 #include<iostream> using namespace std; class Time { public: Time() { h=m=0; } ...

  10. 达人篇:3.1.3)FAI 首件检验

    本章目的:了解FAI. 1)定义: FAI: First Article Inspection Report . 汉语译作:首件全尺寸检验报告. 2)目的 制作FAI报告是为了检查成型后的产品尺寸是否 ...