作者在 2009-06-11 00:58:43 发布以下内容
一、从O(g(n))到O(1)
例:输入字节x,输出x的置换(比特位恰好相反),函数名reverse_bit8。
这个算法很多地方都需要用到。你很快就可以找到很多高效的算法实现它。
比如1:通过逐位测试,按测试结果对结果进行或、移位运算。算法如下:
unsigned char y = 0;
for(int i = 0;i < 8;i++)
{
y = y << 1;
if(x & 0x01)//对最低位进行测试
y = y | 0x01;
x = x >> 1;
}
如果写得高深一点:
unsigned char y = 0;
signed char xx = x;//使用有符号字节类型
for(int i = 0;i < 8;i++)
{
y = y >> 1;
if(xx < 0)//对最高位进行测试
y = y | 0x80;
xx = xx << 1;
}
效率差不多,不知道还有没有比这效率更高的算法了。
很多情况,这个函数需要重复高频调用,所以可以考虑另一种常用方法:查表法。
很简单,所有情况共256种,表的规模不算很大,而且表元素的值就可以通过上面的算法计算出来。最终的reverse_bit8就成了这样:
unsigned char reverse_bit8(unsigned char x)
{
return some_namespace_or_class::pTable[x];
}
另外,当需要使用reverse_bit8之前,需要把这张表准备好。很多人一定想到使用文本文件形式保存这张表,但有更好的方法:保存为二进制文件。这样就不需要通过类型转换将文本中的值读入内存了。当需要读取表的时候,只需要:
FILE* pInFile = fopen("table.dat","rb");
fread(pTable,sizeof(unsigned char),256,pInFile);
如此一来,程序整体效率就提升了很多了。
当然,如果是在windows下,还可以使用文件映射机制,或者使用动态链接库,来快速、方便地初始化甚至直接使用表,可以参看《windows核心编程》。
例:输入字节x,输出x的置换(比特位恰好相反),函数名reverse_bit8。
这个算法很多地方都需要用到。你很快就可以找到很多高效的算法实现它。
比如1:通过逐位测试,按测试结果对结果进行或、移位运算。算法如下:
unsigned char y = 0;
for(int i = 0;i < 8;i++)
{
y = y << 1;
if(x & 0x01)//对最低位进行测试
y = y | 0x01;
x = x >> 1;
}
如果写得高深一点:
unsigned char y = 0;
signed char xx = x;//使用有符号字节类型
for(int i = 0;i < 8;i++)
{
y = y >> 1;
if(xx < 0)//对最高位进行测试
y = y | 0x80;
xx = xx << 1;
}
效率差不多,不知道还有没有比这效率更高的算法了。
很多情况,这个函数需要重复高频调用,所以可以考虑另一种常用方法:查表法。
很简单,所有情况共256种,表的规模不算很大,而且表元素的值就可以通过上面的算法计算出来。最终的reverse_bit8就成了这样:
unsigned char reverse_bit8(unsigned char x)
{
return some_namespace_or_class::pTable[x];
}
另外,当需要使用reverse_bit8之前,需要把这张表准备好。很多人一定想到使用文本文件形式保存这张表,但有更好的方法:保存为二进制文件。这样就不需要通过类型转换将文本中的值读入内存了。当需要读取表的时候,只需要:
FILE* pInFile = fopen("table.dat","rb");
fread(pTable,sizeof(unsigned char),256,pInFile);
如此一来,程序整体效率就提升了很多了。
当然,如果是在windows下,还可以使用文件映射机制,或者使用动态链接库,来快速、方便地初始化甚至直接使用表,可以参看《windows核心编程》。