C语言每日一题(3):实现一个函数来统计二进制中1的个数

标头星空


  • 文章主题:实现一个函数来统计二进制中1的个数
  • 所属专栏:C语言每日一题
  • 作者简介:每天不定时更新C语言的小白一枚,记录分享自己每天的所思所想
  • 个人主页:[₽]的个人主页


前言

函数介绍

该函数的设计为unsigned int Count_1(int num),功能是传入需要求二进制码中有多少个1的变量的数值作为形参,接着因为求出来的数值一定是大于等于0的,我们以无符号整型的形式返回32位中含1的位数。

编程起因

最近刚学过有关于C语言是以32位二进制补码的形式来对一个整数数值以无符号整型或者是整型这两种基础的形式进行储存的,并且也刚学习了所有的位操作符,在想着能不能设计出一个函数来计算出一个数值转化为32位整型形式之后其中含有1的位数(当然改变形参的变量类型的话,也不是不可以求更高位二进值码值中含有1的位数),于是便有了今天这个基于最普通整型参数类型二进制码中为1的位数的函数的设计题目。


设计思路

1.整体逻辑

想求二进制码中有多少个1,就必须先检测最左位或者最右位是否为1接着用左移或者右移操作符移位之后再对其进行赋值从而消去该位的方法,又因为1是最小的左边为1其余全为0的二进制码所对应的并且也是最容易想到和运用的数值,我们便可运用最方便的左移与1相交并判断是否为1后截取赋值回来的操作来实现函数单次的功能,又因为所检测的参数为32位,设置递归的话需要用到静态变量且解决同一问题时递归明显会比循环消耗更多时间,该题用循环设计结构也可以做到很简单,递归的优势不明显,我们便可以设置一个32次的for循环来遍历这个数组,从而实现目标

2.具体逻辑

我设计出了三种方法,具体逻辑可参考代码块中的注释,清晰明了。


代码展示

方法一 :遍历二进制码(常规做法)

#include <stdio.h>
unsigned int Count_1(int);//Count_1()函数声明
int main()
{
	int num = 0;
	printf("Please enter a number:\n");
	scanf("%d", &num);
	printf("\n");
	printf("How many 1s are there in the binary bit?\n");
	printf("%d\n", Count_1(num));
	return 0;
}
unsigned int Count_1(int num)//Count_1()函数定义
{
	unsigned int count = 0;//定义计数器的同时给计数器的初始值赋值为一
	for (int bit = 1; bit <= 32; bit++)//遍历一个数字二进制码(补码)的32位
	{
		if ((num & 1) == 1)//通过每次与数字1进行按位与操作,因为1的二进制码只有最后一位
		                   //为1,所以参数二进制码最后一位之前全部变成0只有最后一位会被取
		                   //到1或0的值,这时二进制的最后一位值与十进制相同,从而可以通过
		                   //十进制的值直接表示该位是0或1,从而判断是否为1
		{
			count++;//该位为1时计数器的值自增1
		}
		num >>= 1;//每判断完一位后自动将往左移一位的二进制码数值赋值给被判断的变量
	}

方法二 :十进制算法模拟二进制左移位及判断位值(难度偏高)

#include <stdio.h>
unsigned int Count_1(unsigned int);//Count_1函数声明,数据类型变成unsigned int可以将十进
                          //制负数模拟成二进制码中通过符号位带了负值但实际上根本未
                          //带负值的情况(将其变成一个很大的值来继续求出余数为1或0
                          //的而非负数的模拟二进制位数)
int main()
{
	int num = 0;
	printf("Please enter a number:\n");
	scanf("%d", &num);
	printf("\n");
	printf("How many 1s are there in the binary bit?\n");
	printf("%d\n", Count_1(num));
	return 0;
}
unsigned int Count_1(unsigned int num)//Count_1函数定义
{
	unsigned int count = 0;
	for (int bit = 1; bit <= 32; bit++)
	{
		count += num % 2;//通过十进制模二运算取出每位余数为1还是2
		num /= 2;//通过整除2的方法取出最后一位之前的倍数作为该数现在所剩的二进制码
		         //对应的数值(类似与十进制里除10降位的操作),来模拟左移位的操作
	}
	return count;
}

方法三:通过按位与每次都能巧妙与掉一个1(难度极高)

#include <stdio.h>
unsigned int Count_1(int);//Count_1()函数声明
int main()
{
	int num = 0;
	printf("Please enter a number:\n");
	scanf("%d", &num);
	printf("How many 1s are there in the binary bit?\n");
    printf("%d\n", Count_1(num));
	return 0;
}
unsigned int Count_1(int num)//Count_1()函数定义
{
	unsigned int count = 0;
	while (num)
	{
		num = num & (num - 1);//极为巧妙的通过减一并按位与之后使二进制码值含1的
		                      //位数减少一个变成了0
		count++;//每消去一个0计数器就会自增1
	}
	return count;
}

效果展现

效果展现


结语

通过实现运用新学知识来解决问题,能加深我们对该知识的深入理解与体悟,在一些情况下也能锻炼我们一题多解的能力。作为刚学编程的小白,可能在一些设计逻辑方面有些不足,欢迎评论区进行指正!看都看到这了,点个小小的赞或者关注一下吧(当然三连也可以~),你的支持就是博主更新最大的动力!让我们一起成长,共同进步!


  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值