查找 char 变量中唯一“1”位的索引的最有效方法(在 C 中)

2024-01-04

这是一道面试题:
您将获得一个名为的 char 变量ch,当您知道它代表一个二进制形式的数字时,它的八位中只有一位等于“1”。 IE。 ,唯一可能的值ch are: 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80.
给定变量ch,我需要编写最有效的代码来获取该“1”位的索引。例如:如果ch == 0x1-> 结果为 0。如果ch == 0x4-> 结果是 2。

最明显的方法是使用 switch-case,但我需要更有效的方法。
您可以在此处进行任何位操作以实现高效实施吗?


An unsigned char变量据说只有 8 位宽。为了对位的位置进行编码,我们只需要 3 位。这意味着我们可以构建一个 24 位“表”,其中按自然顺序包含所有 8 个可能的 3 位答案

111 110 101 100 011 010 001 000 =

0xFAC688

如果你的变量ch已知仅含有一种1位,那么它是 2 的幂。除以ch将按您的索引右移原始值1少量。所以,如果我们将上面的“表”除以你的ch 三次答案将移至结果的最低 3 位

unsigned position = (0xFAC688 / ch / ch / ch) & 0x7;

故事结局。上面的内容可能可以更有效地重写,同时保留一般原则。


请注意,这基本上与基于 De Bruijn 序列的方法中使用的原理相同。然而,De Bruijn 序列的目的是pack当原始“解压”表(如上面的表)不适合整数时的索引表。作为一个“令人不快”的副作用,De Bruijn 序列对索引表进行了重新排序,打破了索引的原始自然序列。这需要额外的重新映射工作才能从 De Bruijn 序列中提取正确的结果。

由于只有 24 位,我们在这里就不存在这个问题,这意味着不需要涉及 De Bruijn 及其伴随的技巧。

另一方面,压缩表需要较短的移位,这将简化(从而优化)除数的计算以实现所需的移位长度。对于 De Bruijn 序列,根本不需要计算除数 - 你的ch已经是了。因此,德布鲁因序列可能很容易变得更加高效。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

查找 char 变量中唯一“1”位的索引的最有效方法(在 C 中) 的相关文章

随机推荐