给定一个byte数组,要求统计byte数组的bitcount,也就是byte数组中为1的位的个数。

Redis提供了位数组数据结构,位数组是相对独立的一个程序,在《Redis设计与实现》(黄建宏著)一书中,对此有详细介绍。

回到问题上来,看到这个问题的第一印象就是暴力。假设byte数组长度为n,那么时间复杂度为8n。

我们的目的就是优化常数。

很容易想到的是用空间换时间,预先打表0~255之间的全部数字的bitcount,用到时直接查表,复杂度将为O(n).

这种方法的缺点在于只能存储8位而不能存储太多,因为随着位数的增加,空间消耗指数级增长。

最高级的一种优化方法建立在位运算基础上。这种方法的思想基于分治算法。

首先两两一组分成16组,然后四四一组分成8组,八八一组分成4组,16、16一组分成两组。

统计各个组内1的个数,然后归并可以通过移位运算和加法运算实现。

#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;
int bitcountBruteForce(char*a,int len){
int s=0;
for(int i=0;i<len;i++){
for(int j=0;j<8;j++){
if(a[i]&(1<<j)){
s++;
}
}
}
return s;
}
int table[1<<8];
int bitcountTable(char*a,int len){
int s=0;
for(int i=0;i<len;i++){
s+=table[int(a[i]&0xff)];
}
return s;
}
int swar(int x){
x=(x&0x55555555)+((x>>1)&0x55555555);
x=(x&0x33333333)+((x>>2)&0x33333333);
x=(x&0x0f0f0f0f)+((x>>4)&0x0f0f0f0f);
x=(x*0x01010101)>>24;
return x;
}
int swar2(int x){
x=(x&0x55555555)+((x>>1)&0x55555555);
x=(x&0x33333333)+((x>>2)&0x33333333);
x=(x&0x0f0f0f0f)+((x>>4)&0x0f0f0f0f);
x=(x&0x00ff00ff)+((x>>8)&0x00ff00ff);
x=(x&0x0000ffff)+((x>>16)&0x0000ffff);//x=(x>>16)+(x&31);
return x;
}
int bitcountSWAR(char*a,int len){
int s=0;
int intLen=len/4;
int left=len%4;
int*ia=(int*)a;
for(int i=0;i<intLen;i++){
s+=swar2(*ia);
ia++;
}
for(int i=intLen*4;i<len;i++){
s+=table[a[i]];
}
return s;
}
void initTable(){
for(int i=0;i<(1<<8);i++){
int s=0;
for(int j=0;j<8;j++){
if(i&(1<<j)){
s++;
}
}
table[i]=s;
}
}
int timeit(int(*f)(char*,int),char*a,int len,int manytimes){
int begtime=time(0);
int res=0;
for(int i=0;i<manytimes;i++){
res=f(a,len);
}
cout<<"ans "<<res<<endl;
int endtime=time(0);
int timeused=endtime-begtime;
return timeused;
}
int main(){
const int n=1e6;
int a[n];
initTable();
srand(time(0));
for(int i=0;i<n;i++){
a[i]=rand();
}
cout<<"brute force "<<timeit(bitcountBruteForce,(char*)a,n*sizeof(int),10)<<endl;
cout<<"table method "<<timeit(bitcountTable,(char*)a,n*sizeof(int),10)<<endl;
cout<<"swar method "<<timeit(bitcountSWAR,(char*)a,n*sizeof(int),10)<<endl;
return 0;
}

统计bytearray中的bitcount的更多相关文章

  1. PHP array_count_values() 函数用于统计数组中所有值出现的次数。

    定义和用法 array_count_values() 函数用于统计数组中所有值出现的次数. 本函数返回一个数组,其元素的键名是原数组的值,键值是该值在原数组中出现的次数. 语法 array_count ...

  2. 华为OJ平台——统计字符串中的大写字母

    题目描述: 统计字符串中的大写字母的个数 输入: 一行字符串 输出: 字符串中大写字母的个数(当空串时输出0) 思路: 这一题很简单,直接判断字符串中的每一个字符即可,唯一要注意的一点是输入的字符串可 ...

  3. sort +awk+uniq 统计文件中出现次数最多的前10个单词

    实例cat logt.log|sort -s -t '-' -k1n |awk '{print $1;}'|uniq -c|sort -k1nr|head -100 统计文件中出现次数最多的前10个单 ...

  4. c程序设计语言_习题1-13_统计输入中单词的长度,并且根据不同长度出现的次数绘制相应的直方图

    Write a program to print a histogram of the lengths of words in its input. It is easy to draw the hi ...

  5. Java基础知识强化之集合框架笔记61:Map集合之统计字符串中每个字符出现的次数的案例

    1. 首先我们看看统计字符串中每个字符出现的次数的案例图解: 2. 代码实现: (1)需求 :"aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:a(5) ...

  6. 学c语言做练习之​统计文件中字符的个数

    统计文件中字符的个数(采用命令行参数) #include<stdio.h> #include<stdlib.h> int main(int argc, char *argv[] ...

  7. 用SQL实现统计报表中的"小计"与"合计"的方法详解

    本篇文章是对使用SQL实现统计报表中的"小计"与"合计"的方法进行了详细的分析介绍,需要的朋友参考下   客户提出需求,针对某一列分组加上小计,合计汇总.网上找 ...

  8. JAVA 统计字符串中中文,英文,数字,空格的个数

    面试题:输入一行字符,分别统计出其中英文字母.中文字符.空格.数字和其它字符的个数 可以根据各种字符在Unicode字符编码表中的区间来进行判断,如数字为'0'~'9'之间,英文字母为'a'~'z'或 ...

  9. Python统计列表中的重复项出现的次数的方法

    本文实例展示了Python统计列表中的重复项出现的次数的方法,是一个很实用的功能,适合Python初学者学习借鉴.具体方法如下:对一个列表,比如[1,2,2,2,2,3,3,3,4,4,4,4],现在 ...

随机推荐

  1. 求通俗讲解下tensorflow的embedding_lookup接口的意思

    https://www.zhihu.com/question/48107602 作者:王凯链接:https://www.zhihu.com/question/48107602/answer/15980 ...

  2. nginx不浏览直接下载文件

    当我们使用Nginx时,如果要让一些附件比如txt,pdf,doc等不直接在浏览器打开,而弹出另存为的对话框(也就是下载),则可以在nginx里添加如下配置: location /{if ($requ ...

  3. (转)C#中的委托(Delegate)和事件(Event)

    转自:http://blog.chinaunix.net/uid-576762-id-2733751.html   把C#中的委托(Delegate)和事件(Event)放到现在讲是有目的的:给下次写 ...

  4. c# event Action 判断事件列表中是否存在这个委托

    using UnityEngine; using System.Collections; using System; public class eventTest : MonoBehaviour { ...

  5. Android OpenGL ES和OpenGL一起学(二)------理解Viewport(视口)和坐标系Android OpenGL ES篇(转帖)

      来自:http://www.cnblogs.com/xiaobo68688/archive/2011/12/01/2269985.html   首先我们在屏幕中心显示一个矩形,效果如图: // 代 ...

  6. [海蜘蛛] 海蜘蛛 V8 全线无限试用版 免费发布破解教程

    http://bbs.p52.cn/forum.php?mod=viewthread&tid=3499&extra=page%3D1&page=1&_dsign=79c ...

  7. 关于ThinkPHP的一些编程技巧

    在TP学习过程中难免会遇到一些大大小小的问题,把这些问题积累下来就可以在以后遇到时能很快速的解决,提高编程效率. 1.让Runtime下的文件格式化:入口文件处:define(‘STRIP_RUNTI ...

  8. JS与Jquery的事件委托

    参考:http://www.ituring.com.cn/article/467 概念: 什么是事件委托:通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委 ...

  9. 生日日期联动选择birthday.js

    实例下载

  10. LintCode:Fibonacci

    C++ class Solution{ public: /** * @param n: an integer * @return an integer f(n) */ int fibonacci(in ...