统计bytearray中的bitcount
给定一个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的更多相关文章
- PHP array_count_values() 函数用于统计数组中所有值出现的次数。
定义和用法 array_count_values() 函数用于统计数组中所有值出现的次数. 本函数返回一个数组,其元素的键名是原数组的值,键值是该值在原数组中出现的次数. 语法 array_count ...
- 华为OJ平台——统计字符串中的大写字母
题目描述: 统计字符串中的大写字母的个数 输入: 一行字符串 输出: 字符串中大写字母的个数(当空串时输出0) 思路: 这一题很简单,直接判断字符串中的每一个字符即可,唯一要注意的一点是输入的字符串可 ...
- sort +awk+uniq 统计文件中出现次数最多的前10个单词
实例cat logt.log|sort -s -t '-' -k1n |awk '{print $1;}'|uniq -c|sort -k1nr|head -100 统计文件中出现次数最多的前10个单 ...
- 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 ...
- Java基础知识强化之集合框架笔记61:Map集合之统计字符串中每个字符出现的次数的案例
1. 首先我们看看统计字符串中每个字符出现的次数的案例图解: 2. 代码实现: (1)需求 :"aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:a(5) ...
- 学c语言做练习之统计文件中字符的个数
统计文件中字符的个数(采用命令行参数) #include<stdio.h> #include<stdlib.h> int main(int argc, char *argv[] ...
- 用SQL实现统计报表中的"小计"与"合计"的方法详解
本篇文章是对使用SQL实现统计报表中的"小计"与"合计"的方法进行了详细的分析介绍,需要的朋友参考下 客户提出需求,针对某一列分组加上小计,合计汇总.网上找 ...
- JAVA 统计字符串中中文,英文,数字,空格的个数
面试题:输入一行字符,分别统计出其中英文字母.中文字符.空格.数字和其它字符的个数 可以根据各种字符在Unicode字符编码表中的区间来进行判断,如数字为'0'~'9'之间,英文字母为'a'~'z'或 ...
- Python统计列表中的重复项出现的次数的方法
本文实例展示了Python统计列表中的重复项出现的次数的方法,是一个很实用的功能,适合Python初学者学习借鉴.具体方法如下:对一个列表,比如[1,2,2,2,2,3,3,3,4,4,4,4],现在 ...
随机推荐
- ORM数据库框架 SQLite ORMLite MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Android开发者选项 介绍
15个必知的Android开发者选项 https://www.jianshu.com/p/07b551ee260b 1.Stay awake 充电时保持屏幕唤醒,开发的时候,时不时的锁屏真是够了,开 ...
- CoffeeScript?TypeScript?还是JavaScript
请注意本文只是我的偏见,我努力地理解借助CoffeeScript或TypeScript之类的编译器写JavaScript代码的理由.静态编译.强类型语言和框架,我有着这些流行的.丰富的背景.我的上一份 ...
- 关于LINQ和SQL操作数据库的性能测试(转)
微软linq技术已经出现很久,很多公司已经开始商业使用,作为我们暂时没有用到的人来说,也应该适当的了解下相关知识,但是直到目前网络上对他的看法仍然是褒贬不一,当然任何事情都不可能完美的,下面就针对大多 ...
- 理解SVG图片标签的viewport、viewBox、preserveAspectRatio缩放
一.viewport 表示SVG可见区域的大小,或者可以想象成舞台大小,画布大小. <svg width="></svg> 上面的SVG代码定义了一个视区,宽500单 ...
- python命令行参数传递JSON串
有点小问题,一是传递的双引号被自动删除了,但是如果用单引号,JSON解析又不认. 所以,最后的方案是,传递单引号,但程序处理时做一个替换,替换成单引号.
- cmake 学习笔记(三) (转)
接前面的 Cmake学习笔记(一) 与 Cmake学习笔记(二) 继续学习 cmake 的使用. 学习一下cmake的 finder. finder是神马东西? 当编译一个需要使用第三方库的软件时,我 ...
- Robot Framework + Selenium library + IEDriver环境搭建
转载:https://www.cnblogs.com/Ming8006/p/4998492.html#c.d 目录: 1 安装文件准备2 Robot框架结构3 环境搭建 3.1 安装Python ...
- ivr
/************************************************************* 北京高阳圣思园信息技术有限公司IVR业务: 流程说明:公司介绍子流程 发布 ...
- conEmu的使用笔记
1.如何让conEmu成为windows的默认控制台程序? 解决:选中settings > Integration > Default Term里的Force ConEmu as defa ...