统计一个Byte中1的个数,算法尽可能高性能——C++实现

本文介绍了四种不同的C++方法来统计一个无符号字符中1的个数,包括对2取模、位操作、位运算优化以及查表法。每种方法都具有不同的时间和空间复杂度,提供了在性能和空间占用之间的权衡。
摘要由CSDN通过智能技术生成
/*统计一个Byte中1的个数,算法尽可能高性能*/
#include <iostream>
using namespace std;

//方法1:对2取模得出最后一位,然后除以2实现右移1位,循环8次
int count1(unsigned char c)
{
	int cnt=0;
	for (int i=0;i!=8;++i)
	{
		cnt+=c%2;
		c=c/2;
	}
	return cnt;
}
//方法2:对0x01执行&操作,统计最右边一位的1,然后右移1位,循环8次,o(n)复杂度
int count2(unsigned char c)
{
	int cnt=0;
	for (int i=0;i!=8;++i)
	{
		cnt+=(c&0x01);
		c>>=1;
	}
	return cnt;
}
//方法3:c=c&(c-1),只统计c中1的个数,循环次数是字节中1的个数,效率比方法2高
int count3(unsigned char c)
{
	int cnt=0;
	while (c!=0)
	{
		c&=(c-1);
		++cnt;
	}
	return cnt;
}
//方法4:查表法,建立一个含有256个整数的数组,每个整数值代表的是c所在的位置含有1的个数
//时间复杂度o(1),空间复杂度o(2^n)
int countTable[256]=
{ 
	0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
	1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
	1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
	2,3,3,4,3,4,4,5,3,4,4,5,4,5,
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Byte Stuffing算法的C实现示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define FLAG 0x7E // 帧头和帧尾标志 #define ESC 0x7D // 转义字符 // 对数据进行字节填充 void byteStuffing(unsigned char* data, int len, unsigned char* stuffedData, int* stuffedLen) { int i, j; unsigned char byte; unsigned char* pos = stuffedData; // 添加帧头 *pos++ = FLAG; for(i = 0; i < len; i++) { byte = data[i]; if(byte == FLAG) { // 如果是帧头或帧尾,则需要进行字节填充 *pos++ = ESC; *pos++ = byte ^ 0x20; } else if(byte == ESC) { // 如果是转义字符,则也需要进行字节填充 *pos++ = ESC; *pos++ = byte ^ 0x20; } else { // 其他情况直接拷贝 *pos++ = byte; } } // 添加帧尾 *pos++ = FLAG; *stuffedLen = pos - stuffedData; } // 对数据进行字节反填充 void byteUnstuffing(unsigned char* stuffedData, int len, unsigned char* data, int* dataLen) { int i, j; unsigned char byte; unsigned char* pos = data; // 跳过帧头 pos++; len--; for(i = 0; i < len; i++) { byte = *stuffedData++; if(byte == ESC) { // 如果是转义字符,则进行反填充 byte = *stuffedData++ ^ 0x20; } *pos++ = byte; } // 跳过帧尾 pos--; *dataLen = pos - data; } int main() { unsigned char data[] = {0x7E, 0x01, 0x02, 0x7D, 0x7E, 0x03, 0x7D, 0x7D, 0x04, 0x7E}; int len = sizeof(data) / sizeof(data[0]); unsigned char stuffedData[2 * len]; int stuffedLen; byteStuffing(data, len, stuffedData, &stuffedLen); printf("Stuffed Data: "); for(int i = 0; i < stuffedLen; i++) { printf("%02X ", stuffedData[i]); } printf("\n"); unsigned char unstuffData[len]; int unstuffLen; byteUnstuffing(stuffedData, stuffedLen, unstuffData, &unstuffLen); printf("Unstuff Data: "); for(int i = 0; i < unstuffLen; i++) { printf("%02X ", unstuffData[i]); } printf("\n"); return 0; } ``` 输出结果: ``` Stuffed Data: 7E 01 02 7D 5E 7E 03 7D 5D 04 7E Unstuff Data: 7E 01 02 7D 7E 03 7D 7D 04 7E ``` 可以看到,字节填充和反填充都能正常工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值