• 学习交流加(可免费帮忙下载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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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");elseprintf("25 not in\n");if (is_in_bitarray(bitarr, 30) != 0)printf("30 in\n");elseprintf("30 not in\n");
}

以上是对位数组概念的理解,以及如何创建位数组!
在VS中运行结果如下:

  • 下面来解决我们最开始留下的笔试题:

一个 4096位的bit数组,要找出前10个二进制的1 所在的位置,麻烦写一个函数来实现。

假设我们这个数组存储的是char类型的512字节,我们利用上面的函数,来构造bit数组,可以往特定的位填1,然后写出函数来查找前10个1所在的位置,并返回位置:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>  #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语言实现位数组(bit数组)与位数组的简单应用举例相关推荐

  1. c语言位数组如何实现,C语言实现位数组(bit数组)与位数组的简单应用举例

    学习交流加(可免费帮忙下载CSDN资源): 个人微信: liu1126137994 学习交流资源分享qq群1(已满): 962535112 学习交流资源分享qq群2: 780902027 今天有朋友遇 ...

  2. 字节转换比特位c语言,C语言实现双字节在数组中按比特位移动

    先说一下应用场合,在LED点阵显示屏中,为了节省flash空间,常用一个bit位来标记哪个灯是否点亮.为了做出比较炫的效果,比如16 * 16像素gif动画边边移动边跳跃.就应用到该思想. 双字节是1 ...

  3. 【C 语言】指针 与 数组 ( 指针 | 数组 | 指针运算 | 数组访问方式 | 字符串 | 指针数组 | 数组指针 | 多维数组 | 多维指针 | 数组参数 | 函数指针 | 复杂指针解读)

    相关文章链接 : 1.[嵌入式开发]C语言 指针数组 多维数组 2.[嵌入式开发]C语言 命令行参数 函数指针 gdb调试 3.[嵌入式开发]C语言 结构体相关 的 函数 指针 数组 4.[嵌入式开发 ...

  4. Algorithm:C++/python语言实现之求旋转数组最小值、求零子数组、求最长公共子序列和最长公共子串、求LCS与字符串编辑距离

    Algorithm:C++/python语言实现之求旋转数组最小值.求零子数组.求最长公共子序列和最长公共子串.求LCS与字符串编辑距离 目录 一.求旋转数组最小值 1.分析问题 2.解决思路 二.求 ...

  5. C语言数组名、数组名取地址、数组首元素地址之间的关系

    C语言中数组名a.数组名取地址&a.数组首元素地址&a[0]三者的概念有点绕,花了点时间好好琢磨了一下,将自己的理解记录下来,如有错误之处,欢迎赐教. 首先看下面的一小段代码: #in ...

  6. 一文搞懂C语言如何用指针来代替变量和数组进行数据的存储

      众所周知,指针的用法最常见的无外乎两种,一种是用指针来指向变量的内存地址,通过操控指针进而可以间接的操控变量.另外一种是把指针当成变量来使用,像变量一样可以存储数据.数组也是类似的道理,因为数组实 ...

  7. C语言 数组的指针和指向数组的指针变量

    一.回顾二维数组和多维数组的概念 int a[3][4];  //二维数组 int a[2][3]4];  //多维数组 二.指向多维数组的指针和指针变量的探究 可以把a看成是一个一维数组,这个一维数 ...

  8. C语言高级专题(4)-------指针和数组的高级应用

    目录 一,指针数组与数组指针 二,函数指针 三,typedef关键字 四,二重指针 五,二维数组 一,指针数组与数组指针 1.字面意思来理解指针数组与数组指针 指针数组的实质是一个数组,这个数组中存储 ...

  9. C语言编写杨辉三角(二维数组方法)

    C语言实现杨辉三角(二维数组) 杨辉三角是什么 杨辉三角,是二项式系数在三角形中的一种几何排列,中国南宋数学家杨辉1261年所著的<详解九章算法>一书中出现.在欧洲,帕斯卡(1623--- ...

最新文章

  1. CPU深夜狂飙,一帮大佬都傻眼了...
  2. Silverlight学习笔记之文字特效之ImageBrush
  3. 记录一些精品开源项目
  4. Php官方指导安装与配置
  5. Python字符串函数说明(菜鸟教程里面的)
  6. nohup + 保证服务后台运行不中断
  7. catti二级笔译综合能力真题_2006年-2011年CATTI二级笔译综合能力试题及答案2018年.doc...
  8. Matlab Tricks(十九)—— 序列左右移的实现
  9. jQuery Ajax 前端和后端数据交互的问题
  10. 剪贴画制作相关资源收集
  11. varchar长度可以任意设置吗_户内金属软管长度可以超过2m吗?
  12. div contenteditable=true各个浏览器上的解析
  13. idea怎么集成svn服务端,使用Mac自带svn搭建服务器,并使用idea进行连接(示例代码)...
  14. 遗传算法原理与应用详解
  15. 求大佬发一个unity curvy的资源包啊
  16. 你还不了解QQ聊天是如何实现的吗?手把手教你实现网络聊天室
  17. Transformer主干网络——ViT保姆级解析
  18. c语言编程定位的计算机,高校计算机专业C语言教学的四个定位
  19. 决策树与随机森林初探
  20. vue watch store

热门文章

  1. Redisson(2-1)分布式锁实现对比 VS Java的ReentrantLock之tryLock
  2. 如何改typecho主题头像_细节决定成败,抖音昵称、头像、简介、视频封面的重要性...
  3. 动态规划C++实现--换钱的方法数(二)(动态规划及其改进方法)
  4. 左神---基础提升笔记
  5. 计算机编程那个好学点,计算机编程好学吗?
  6. 第21届国际足联世界杯观后感
  7. 史上最全的WebSettings说明
  8. 纯CSS实现三角形图标
  9. Nape 碰撞检测事件 笔记
  10. HTTPS为什么安全 分析 HTTPS 连接建立全过程