c语言位数组如何实现,C语言实现位数组(bit数组)与位数组的简单应用举例
学习交流加(可免费帮忙下载CSDN资源):
个人微信: liu1126137994
学习交流资源分享qq群1(已满): 962535112
学习交流资源分享qq群2: 780902027
今天有朋友遇到一个笔试题:一个 4096位的bit数组,要找出前10个二进制的1 所在的位置,麻烦写一个函数来实现
bit数组对我来说是一个新的概念,故整理资料学习bit数组的概念~
加qq1126137994一起学习更多技术!!!
文章目录
1、位数组的概念
将一个整数添加到二进制数组中 :
判断一个整数是否在二进制数组中
删除二进制数组中的一个整数
完整代码
1、位数组的概念
所谓的位数组,主要是为了有效地利用内存空间而设计的一种存储数据的方式。在这种结构中一个整数在内存中用一位(1 bit)表示。这里所谓的表示就是如果整数存在,相应的二进制位就为1,否则为0。
主要思想:我们知道一个 char 类型的数据在内存中占用 1Byte(即 8 bit),如果我们用二进制位在内存中的顺序来代表整数则可以存储更多的信息。
这样的话,一个 char 类型可以存储 8个整数。假设 a是一个 char 数组的话,整数8就可以用 a[1] 的第一个二进制位表示了。那么512字节就是4096位,第一位代表0,第二位代表1,第三位代表2,第4096位代表4095,这样我们就可以用512字节存储4096个数了,大大的节省了内存空间。
这里的关键就是 一个char型能表示8个整数。
下面我实现一种利用 char 数组构造一个二进制数组。主要包括以下三个方面::
将一个整数添加到二进制数组中 :
void add_to_bitarray(char *bitarr, int num){ /* num代表要插进数组中的数 */
bitarr[num >> SHIFT] |= (1 << (num & MASK)); /* MASK 为 0x7 */
}
该方法的主要作用是将二进制数组中表示该整数的位置为1。首先我们得找到该整数位于 char 数组的第几个元组中,这里利用该整数除以8即可(代码中除以8用右移三位实现),例如整数25位于25/8 = 3 余 1,表明该整数是用char 数组的第四个元素的第二位表示。那么在该元素的第几位可以利用该整数的后三位表示(0~7刚好可以表示8个位置),即 25 & 0x7 = 1,则代表25在该元素的第二位。将相应位置1,可以先将整数1左移相应位数,然后与二进制数组进行或操作即可。
判断一个整数是否在二进制数组中
int is_in_bitarray(char *bitarr, int num){
return bitarr[num >> SHIFT] & (1 << (num & MASK));
}
先找到该整数在二进制数组中的位置,然后判断该位是否为1,若是则表示该整数位于二进制数组中,反之不在数组中。
删除二进制数组中的一个整数
void clear_bitarray(char *bitarr, int num){
bitarr[num >> SHIFT] &= ~(1 << (num & MASK));
}
思路相同,先找到该整数在二进制数组中的位置,然后将该位置为0即可。
完整代码
完整的代码如下:
#include
#include
#include
#define SHIFT 3
#define MASK 0x7
char *init_bitarray(int);
void add_to_bitarray(char *, int);
int is_in_bitarray(char *, int);
void clear_bitarray(char *, int);
void test(char *);
int main(){
char *arr;
arr = init_bitarray(100);
add_to_bitarray(arr, 25);
test(arr);
clear_bitarray(arr, 25);
test(arr);
getchar();
return 0;
}
char *init_bitarray(int size){
char *tmp;
tmp = (char*)malloc(size / 8 + 1);
memset(tmp, 0, (size / 8 + 1)); //initial to 0
return tmp;
}
void add_to_bitarray(char *bitarr, int num){ /* num代表要插进数组中的数 */
bitarr[num >> SHIFT] |= (1 << (num & MASK));
}
int is_in_bitarray(char *bitarr, int num){
return bitarr[num >> SHIFT] & (1 << (num & MASK));
}
void clear_bitarray(char *bitarr, int num){
bitarr[num >> SHIFT] &= ~(1 << (num & MASK));
}
void test(char *bitarr){
if (is_in_bitarray(bitarr, 25) != 0)
printf("25 in\n");
else
printf("25 not in\n");
if (is_in_bitarray(bitarr, 30) != 0)
printf("30 in\n");
else
printf("30 not in\n");
}
以上是对位数组概念的理解,以及如何创建位数组!
在VS中运行结果如下:
下面来解决我们最开始留下的笔试题:
一个 4096位的bit数组,要找出前10个二进制的1 所在的位置,麻烦写一个函数来实现。
假设我们这个数组存储的是char类型的512字节,我们利用上面的函数,来构造bit数组,可以往特定的位填1,然后写出函数来查找前10个1所在的位置,并返回位置:
#include
#include
#include
#define N_bit 4096
#define SHIFT 3
#define MASK 0x7
char *init_bitarray(int);
void add_to_bitarray(char *, int);
char *init_bitarray(int size){
char *tmp;
tmp = (char*)malloc(size / 8 + 1);
memset(tmp, 0, (size / 8 + 1)); //initial to 0
return tmp;
}
void add_to_bitarray(char *bitarr, int num){ /* num代表要插进数组中的数 */
bitarr[num >> SHIFT] |= (1 << (8 - (num & MASK)));
}
void add_1_to_bitarr(char *bit_arr)
{
add_to_bitarray(bit_arr, 25);
add_to_bitarray(bit_arr, 28);
add_to_bitarray(bit_arr, 23);
add_to_bitarray(bit_arr, 67);
add_to_bitarray(bit_arr, 35);
add_to_bitarray(bit_arr, 36);
add_to_bitarray(bit_arr, 55);
add_to_bitarray(bit_arr, 69);
add_to_bitarray(bit_arr, 44);
add_to_bitarray(bit_arr, 97);
add_to_bitarray(bit_arr, 421);
add_to_bitarray(bit_arr, 564);
add_to_bitarray(bit_arr, 987);
add_to_bitarray(bit_arr, 684);
add_to_bitarray(bit_arr, 986);
add_to_bitarray(bit_arr, 658);
add_to_bitarray(bit_arr, 354);
add_to_bitarray(bit_arr, 764);
add_to_bitarray(bit_arr, 691);
add_to_bitarray(bit_arr, 36);
add_to_bitarray(bit_arr, 345);
}
int main()
{
char *bit_arr;
bit_arr = init_bitarray(4096);
add_1_to_bitarr(bit_arr);
int num[10];
int k = 1;
for (int i = 0; i < N_bit / 8 + 1; i++)
{
for (int j = 1; j < 8 && k <= 10; j++)
{
if ((bit_arr[i] & 128) == 128)
{
num[k] = i * 8 + j + 1;
k++;
}
bit_arr[i] <<= 1;
}
}
for (int n = 1; n <= 10; n++)
{
printf("第%d个1位置为:%d位\n", n, num[n]);
}
//getchar();
return 0;
}
运行结果为:
我们看到前10 个1 的位置都比我们填入到数组中的位置大1,是因为我们认为4096位是从第一个1开始,而数组是从第0号开始,所以产生了偏移!!!
到此我们已经用了一种方法来解决这个笔试题,同时也学会了一个新的概念,位数组!!!
c语言位数组如何实现,C语言实现位数组(bit数组)与位数组的简单应用举例相关推荐
- C语言实现位数组(bit数组)与位数组的简单应用举例
学习交流加(可免费帮忙下载CSDN资源): 个人微信: liu1126137994 学习交流资源分享qq群1(已满): 962535112 学习交流资源分享qq群2: 780902027 今天有朋友遇 ...
- c语言不定长数组_学习C语言这三块“硬骨头”不搞定学了也是白学
C语: C语言在嵌入式学习中是必备的知识,审核大部分操作都要围绕C语言进行,而其中有三块"难啃的硬骨头"几乎是公认级别的. 01指针 C语言 指针公认最难理解的概念,也是让很多初学 ...
- c语言uint8的数组怎么转换为uint32_剖析JS和Redis的数据结构设计:数组
语言的数据结构相通性 最近读了Redis的原理实现,感受到程序语言的相通性,只要你掌握了语言的共性,触类旁通其他语言的开发就变得非常简单了. 总体来说,各种程序语言底层的设计思想是非常相通的,首先针对 ...
- c++什么时候数组溢出_C语言,营养丰富的C语言五,变长数组不是动态数组
大家好,感谢朋友的支持阅读和关注,虽然我提出的这些小知识点看得人很少,但是每涨一个阅读和关注,都能让我开心很久,所以再次感谢一起学习的朋友们. 查余补漏: 在前几次的讲解中,有朋友提出C语言的内存分配 ...
- c语言3到7位水仙花数流程图_C语言入门基础整理
学习计算机技术,C语言可以说是必备的,他已经成为现在计算机行业人学习必备的,而且应用也是十分的广泛,今天就来看看拥有几年c语言工作经验的大神整理的C语言入门基础知识,没有学不会,只有不肯学. 结构化程 ...
- C语言基础1:初识C语言(转义、注释;数组、操作符、反码、补码、static、define、指针、结构体常变量;局部变量;作用域、生命周期)
文章目录 C语言基础1:初识C语言 1.C语言简介 1.1什么是C语言 1.2C语言的发展 2.第一个C语言程序 2.1创建项目 2.2添加源文件 2.3写代码 3.数据类型 4.变量.常量 4.1定 ...
- 深入浅出C语言:(三)C 语言数组指针(指向数组的指针)
目录 一.C 语言数组指针(指向数组的指针) 二.C 语言字符串指针(指向字符串的指针) 三.C 语言指针数组(数组每个元素都是指针) 四.二维数组指针(指向二维数组的指针) 五.指针数组和二维数组指 ...
- 初识C语言(1)(2)(3)(4) C语言入门 保姆级教程 变量 常量 字符串 转义字符 操作符 关键字 字符串 指针 函数 结构体 数组 选择语句 循环语句
一.如何写C语言代码 1.编译器 2.创建项目 3.创建源文件 4.写代码 5.编译+链接+运行 项目名字不要汉语,不要特殊字符,不要加空格,项目路径一般为你想要的路径 C语言中,一般创建.c源文件, ...
- c语言怎样统计数组的长度,C语言指针难吗?纸老虎而已,纯干货讲解
原标题:C语言指针难吗?纸老虎而已,纯干货讲解 指针对于C来说太重要.然而,想要全面理解指针,除了要对C语言有熟练的掌握外,还要有计算机硬件以及操作系统等方方面面的基本知识.所以本文尽可能的通过一篇文 ...
最新文章
- python3.x安装cv2失败
- SurfaceView-----------------转
- 云信小课堂|如何实现音视频通话
- aix服务器端口配置文件,aix配置(IP,子网掩码,DNS)网络接口的三种方式
- (详解)你应该知道的new操作符
- Oracle数据库中正确的导入dmp数据库文件
- 使用Aptana搭建Python开发环境
- oracle imp 跳过表,关于oracle imp 导入避开若干表
- python有理数_有理数生成器(Python)
- datetime instant 转_java8 Instant 时间及转换操作
- Mybatis实现订单案例的五表联合操作
- Paraphrasing effectively 有效转述你需要了解这些内容~
- 未来10年互联网的十大发展趋势
- 【LeetCode】322. 零钱兑换 结题报告 (C++)
- 大话商学院(3)--有一种网络效应叫赢者通吃
- 混合高斯模型介绍以及应用
- altium designer拼版例子
- 2021 年春招和往年相比会有什么不同,应该如何准备?
- 1688商品详情接口
- CSS实现的撕纸效果
热门文章
- 工业相机之常见参数|视觉硬件篇
- 《大数据机器学习实践探索》 ---- 大数据机器学习:spark mlib 库【简介 与 架构初探】
- 怎么用计算机打出错误,电脑连接打印机怎么一直显示错误怎么办
- 使用imagick将PDF转换成图片时报Fatal error: Uncaught exception 'ImagickException' with message 'FailedToExecute
- python tcl tk_安装Python WARNING: The version of Tcl/Tk (8.5.9)
- OpenCV人脸识别之Eigenface算法(PCA特征脸方法)
- ubuntu16.04,解决桌面右键菜单失效问题!
- [poj1797] Heavy Transportation
- php中调用css设置表格,CSS表格设置实例
- 华为首个芯片工厂封顶!