比特选择算法

时间:2017-12-06 14:25:53

标签: c algorithm bit-manipulation

我想找到一种有效的方法,使用C中另一个流的位从一个流中选择位。处理的数据量是太字节,因此速度很重要。

“位选择器”的作用是仅从位序列中选择某些位。例如,如果源流是[1,0,1,0,1,0,1]并且选择标准是[1,1,0,0,1,0,0],那么结果将是[1 ,0,1]。

执行以下操作的示例:

uint64_t source[5];
source[0] = 1234567890987654321;
source[1] = 3456789098765432198;
source[2] = 5678909876543219876;
source[3] = 7890987654321987654;
source[4] = 9098765432198765432;
uint64_t selector[5];
selector[0] = 8214263800482614621;
selector[1] = 4251759498365531188;
selector[2] = 1628009771533217836;
selector[3] = 6890182644227957152;
selector[4] = 3018964452491735032;
size_t count_values = 5;
uint64_t result[5];

size_t xCurrentResultBits = 0;
uint64_t result_value = 0;
size_t result_index = 0;
for( size_t xSelector = 0; xSelector < count_values; xSelector ){
   uint64_t current_selector = selector[ xSelector ];
   uint64_t current_source = source[ xSelector ];
   for( size_t bit = 0; bit < 64; bit++ ){
      uint64_t mask = 1;
      mask = mask << bit;
      uint64_t selector_value = current_selector | mask;
      if( selector_value > 0 ){ // keep the bit in the source
         uint64_t source_value = current_source | mask;
         result_value = result_value << 1;
         if( source_value > 0 ) result_value = result_value + 1;
         xCurrentResultBits++
      } else {
         // throw away source bit
      }
      if( xCurrentResultBits == 63 ){ // filled up a result value
         result[ result_index ] = result_value;
         result_index++;
         result_value = 0;
         xCurrentResultBits = 0;
      }
   }
}

问题是这种方法可能比它慢很多。有一个众所周知的算法可以快速完成吗?

1 个答案:

答案 0 :(得分:0)

我会逐字节地查找并基于查找表。

创建一个查找表,该表可以为您提供或者(在移位之后)到输出的当前和下一个字节的位模式。该表由[sourceByte] [selectorByte]索引,因此它是一个256 * 256的字节值表。

将表结果按当前输出字节中已经占用的位数移动,将OR移位到当前和下一个字节(或者可以使用更大的块来获得结果)。

将输出位位置和字节指针提高选择器字节的位数(另一个表字节[256]可能比位操作更容易)。

但是最后,你必须对程序进行分析,并尝试哪种方法更快(并且如果这种方法真的占用了运行时的显着部分)。