C++ 中有趣的位掩码谜题
Posted
技术标签:
【中文标题】C++ 中有趣的位掩码谜题【英文标题】:Interesting bitmask puzzle in C++ 【发布时间】:2012-05-05 11:01:51 【问题描述】:我有一个有趣的位掩码难题,我需要帮助解决一些问题。问题来了:
11010
每个位代表一段内容的一个特征。它存储在 Redis 中。但是要查询它,我们需要每个组合,以便我们可以拉出密钥。所以11010
会产生这些组合:
11010
10000
10010
11000
01010
00010
01000
有人有 C++ 的解决方案吗?
【问题讨论】:
所以基本上你需要类似if (search_key & item_key) != 0) ...
的东西?
如何在 n^2 中解决?你是说 2^n 吗?
您是否在问如何在不到 2^n 的时间内生成最多 2^n 个值的列表?认真的吗?
似乎是集合问题的所有子集。这是一个指数算法!
啊,看,所以我们需要做的就是确保 n 足够小。然后 2^n 击败 n^2。问题解决了。
【参考方案1】:
请参阅Chess Programming Wiki,了解初始位掩码的子集数量呈线性关系的算法。将 n 位设置为 1 时,该数字等于 2^n,因此它是设置位数的指数。
// enumerate all subsets of set d
void enumerateAllSubsets(U64 d)
U64 n = 0;
do
doSomeThingWithSubset(n);
n = (n - d) & d;
while ( n );
【讨论】:
谢谢,太好了!我会阅读这个。感谢大家的帮助!【参考方案2】:如果 2^n (n=bits set) 大于您拥有的键数,则可能会更快地解决问题。也就是说,获取您的键列表并根据位掩码测试它们,而不是枚举可能的键并检查值。
【讨论】:
以上是关于C++ 中有趣的位掩码谜题的主要内容,如果未能解决你的问题,请参考以下文章