寻找更高效的位域解码算法
Looking for a more efficient bitfield decode algorithm
我有一个Visual Studio 2008 C++应用程序,我在其中接收位图(不是图像)。翻转的每个位对应于解码图上的一个位置。
typedef unsigned char BYTE;
const unsigned int COL_COUNT = 8;
const unsigned int ROW_COUNT = 4;
static char g_decode_map[ ROW_COUNT ][ COL_COUNT ] =
{
{ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' },
{ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' },
{ 'q', 'r', 's', 't', 'u', 'v', 'w', 'x' },
{ 'y', 'z', ',', '.', ' ', ':', '-', '+' }
};
// current implementation
void Decode( const BYTE bitmap[ ROW_COUNT ],
const char decode_map[ ROW_COUNT ][ COL_COUNT ],
char decoded[ ROW_COUNT * COL_COUNT ] )
{
int found = 0;
for( int i = 0; i < ROW_COUNT; ++i )
{
for( int j = 0; j < COL_COUNT; ++j )
{
if( std::bitset< COL_COUNT >( bitmap[ i ] ).test( j ) )
{
decoded[ found++ ] = g_decode_map[ i ][ COL_COUNT - j - 1 ];
}
}
}
}
int main( int argc, char* argv[] )
{
BYTE bitmap[ ROW_COUNT ] = { 0x01, 0x80, 0x00, 0x00 };
// expected output { 'h', 'i' } or { 'i', 'h' } order is unimportant
char decoded[ ROW_COUNT * COL_COUNT + 1 ] = { };
Decode( bitmap, g_decode_map, decoded );
printf( "Decoded: %srn", decoded );
return 0;
}
我目前的解码实现工作正常,但我觉得可能有更有效的方法可以做到这一点。有人可以建议一种性能更高的算法吗?
测试每个位是否使用按位运算设置会更快,而不是为每个测试的位创建位集。 尝试这样的事情:
for( int i = 0; i < ROW_COUNT; ++i ) {
for( int j = 0; j < COL_COUNT; ++j ) {
if(bitmap[i] & (1 << j)) {
...
1 << j
生成的掩码仅包含您要测试集的位。 仅当该位设置为bitmap[i]
时,才使用位图字节按位和掩码返回 true。 这个条件的结果应该等同于你的条件的结果,而且应该快很多。
您正在执行 64 个条件检查。 32 个在 for 循环中,32 个在 for 循环中。如果你不能摆脱 for 循环中的 32,你能做的最好的事情就是循环展开以减少 forloop 执行的条件语句的数量。行和列长度定义为常量。您可以展开循环并对索引的一些数字进行硬编码。与其使用内部 for 循环,不如编写 8 if 语句,如下所示。
这就留下了一个问题,如果有人更改常量值怎么办?然后代码中断。这是正确的。如果你需要它足够健壮来承受这一点,你可以使用编译时递归来展开循环(下面的链接)。此外,任何看过你的代码的人都会畏缩不前,认为你是神。:P 此外,Jason的解决方案也会加快速度。
if( std::bitset< COL_COUNT >( bitmap[ i ] ).test( 0 ) )
if( std::bitset< COL_COUNT >( bitmap[ i ] ).test( 1 ) )
if( std::bitset< COL_COUNT >( bitmap[ i ] ).test( 2 ) )
if( std::bitset< COL_COUNT >( bitmap[ i ] ).test( 3 ) )
...
if( std::bitset< COL_COUNT >( bitmap[ i ] ).test( 7 ) )
编译时循环(答案 #1)
模板元编程
这是快速完成的方法,假设COL_COUNT == 8
(要真正快速地完成它,请使用内联汇编器):
for( int i = 0; i < ROW_COUNT; ++i )
{
unsigned char next_byte = bitmap[i] ;
for( int j = 0; j < COL_COUNT; ++j )
{
if (next_byte & 0x80)
{
decoded[ found++ ] = g_decode_map[ i ][ j ];
}
next_byte <<= 1 ;
}
}
我已经编写了它以重现您的程序的行为 - 但您确定您是正确的吗?我希望您每次都增加found
,而不仅仅是在找到1
位时。
相关文章:
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- C++A*算法并不总是在路径中具有目标节点
- 排序算法c++
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 算法问题:查找从堆栈中弹出的所有序列
- 下面是排序算法O(n)吗
- 无法解码base64+deflate数据
- KMP算法和LPS表构造的运行时间
- 为什么我的排序算法会更改数组值
- 求最大元素位置的分治算法
- 具有非整数边容量的最大流量的Dinic算法
- 到连接组件算法的问题(递归)
- 正在解码MSVC 32位版本的程序集(作业).没有手术做什么
- 使用霍夫曼树解码算法/实现
- 寻找更高效的位域解码算法
- 霍夫曼解码算法
- 对shannon-fano编码算法生成的代码进行解码