我有一个算法来搜索包含64个字节值的数组,我想找到一个4位值,看看它在数组中出现了多少次。例如,数组中的第一个元素可能是10101010,4位值是1010,其中只计算一次。如果下一个元素是10000000,那么这将被计为0.如果我们的4位结果存在,那么很容易遍历数组中的所有元素并检查每个元素但是有更快的方法吗?
答案 0 :(得分:2)
precompute:
- 4bit key offset by 0bit
- 4bit key offset by 1bit
- 4bit key offset by 2bit
- 4bit key offset by 3bit
- 4 bit mask offset by 0bit
- 4 bit mask offset by 1bit
- 4 bit mask offset by 2bit
- 4 bit mask offset by 3bit
for each byte in bytes:
for each offset:
mask out bytes we care about
check if it matches our precomputed key
O(n)
。 通过将键一次向左移位一位,并通过在掩码中将4个相关位设置为1来完成键和掩码的预计算。
match = (bytes[i] & (0x0F << offset)) == (key << offset)
某些key
和每个偏移0-3
的。由于(key << offset)
和(0x0F << offset)
将在每四个循环中重复使用,因此预先计算四个值并展开循环将会更快。您的编译器可能会为您执行此操作,但如果没有,请按以下步骤操作:
matches = 0
for (int i = 0; i < 64; i += 4) {
const mask0 = 0x0F << 0
const key0 = key << 0
match0 = (bytes[i+0] & mask0) == key0
const mask1 = 0x0F << 1
const key1 = key << 1
match1 = (bytes[i+1] & mask1) == key1
...
matches += match0 + match1 + match2 + match3
}