描述:轮转缓冲区bits(含size位),将位值向左移动count位。此操作完成后,处于最左端的count位移动到缓冲区的最右端,而且其他的位也相应的轮转。
复杂度:O(nB),其中B为每个缓冲区中位的个数,n为要轮转到左边的位数。
位操作的实现与分析每个位操作都可操作缓冲区中的数据,缓冲区由无符号字符作为指针来指定。该指针指向足够多的字节来表示缓冲区中的位数。如果缓冲区中的位数不是8的倍数,那么说明最后一个字节的某些位没有使用。
bit_get
bit_get操作获取缓冲区中一个位的状态。要做到这一点,首先要确定位所在的字节,然后通过一个掩码从字节中获取相应的位。掩码中设置为1的位是将要从字节中读出的位,用一个循环操作将此位移动到适当的位置,通过索引bits中相应的字节,并应用调用后的掩码,可以获取所需的位。
bit_get的时间复杂度为O(1)。这是因为获取缓冲区中的位的状态所进行的操作都能够在固定的时间内完成。
bit_set
bit_set 操作设置缓冲区中的一个位的状态。此操作与bit_get的工作方式相似,只是它是利用掩码设置指定的位的状态,而bit_get是获取指定位的状态。
bit_set的时间复杂度为O(1)。这是因为获取缓冲区中位的状态所进行的所有操作都能够在固定的时间内完成。
bit_xor
bit_xor对两个缓冲区bits1和bits2进行按位异或运算,并将计算的结果放到缓冲区bitsx中。要做到这一点,将bits1中第i个位置的位与bits2中第i个位置的位进行比较,如果位值相同,将第i个位置的位置为0;否则,将第i个位置的位置为1。这个过程持续下去直到缓冲区中size指定的每个位都计算完成。
bit_xor的时间复杂度为O(B),其中B是每个缓冲区中的位数。这是因为此操作要在每个位上循环迭代一次。
bit_rot_left
bit_rot_left将缓冲区指定数量的位向左轮转。首先,保存最左端字节的最左端的位,然后向左一位一位地移动每个字节的位值。在移动字节的过程中,将前一个字节最右边的位移动到当前字节的最左边。当处理到最后一个字节时,将其最右边的位移动到首字节的最高位上。这个过程一直持续下去直到所有的位都轮转到位。
bit_rot_left的时间复杂度为O(nB),其中n为要向左轮转的位的个数,B是缓冲区中位的个数。这是因为,对于每次轮转,要进行(B/8)+1次移动。
示例:位操作的实现
/*bit.c 位操作的实现*/
#include <stdlib.h>
#include "bit.h"
/*bit_get 获取缓冲区bits中处于pos位的状态*/
int bit_get(const unsigned char *bits, int pos)
{
unsigned char mask;
int i;
/*设置掩码*/
mask = ox80;
for(i=0; i<(pos % 8); i++)
mask = mask >> 1;
/*用位与运算获取对应的位*/
return (((mask & bits[(int)(pos / 8)]) == mask)? 1:0)
}
/*bit_set 设置缓冲区bits中位于pos位的状态*/
void bit_set(unsigned char *bits, int pos, int state)
{
unsigned char mask;
int i;
/*设置掩码*/
mask = ox80;
for(i=0; i<(pos % 8); i++)
mask=mask>>1;
/*依据state设置位*/
if(state)
bits[pos/8] = bits[pos/8] | mask;
else
bits[pos/8] = bits[pos/8] & (~mask);
return;
}
/*bit_xor 按位异或运算*/
void bit_xor(const unsigned char *bits1,const unsigned char *bits2,unsigned char *bitsx,int size)
{
int i;
/*计算两个缓冲区的按位异或*/
for(i=0;i<size;i++)
{
if(bit_get(bits1,i) != bit_get(bits2,i))
bit_set(bitsx,i,1);
else
bit_set(bitsx,i,0);
}
return;
}
/*bit_rot_left 轮转缓冲区bits(含size位),将位值向左移count位*/
void bit_rot_left(unsigned char *bits,int size,int count)
{
int fbit,lbit,i,j;