我有两个序列:
1. 无符号64位数k的倍数,例如k=5:{0, 5, 10, 15, 20, 25, ...} 2. 64位掩码m的子集加上64位常数C,例如m=0b1011:{C+0, C+1, C+2, C+3, C+8, C+9, C+10, C+11}。注意:C与m不相交,即(m & C) = 0。
除了逐个检查每个k的倍数并检查是否符合第二个序列的条件,或者检查掩码m的每个子集并与C进行OR运算,并检查是否能被k整除之外,还有其他方法可以枚举这两个序列的所有交集吗?
一个64位的数字P在这两个序列的交集中,如果P % k == 0,并且(P & C) == C,并且(P & ~(C | m)) = 0。
注意:枚举第二个序列实际上非常容易。
编辑:枚举的顺序并不重要。
另外:我并不完全希望列举出所有的交集,但我想要一个可以始终前进并获取下一个交集的迭代器。
1. 无符号64位数k的倍数,例如k=5:{0, 5, 10, 15, 20, 25, ...} 2. 64位掩码m的子集加上64位常数C,例如m=0b1011:{C+0, C+1, C+2, C+3, C+8, C+9, C+10, C+11}。注意:C与m不相交,即(m & C) = 0。
除了逐个检查每个k的倍数并检查是否符合第二个序列的条件,或者检查掩码m的每个子集并与C进行OR运算,并检查是否能被k整除之外,还有其他方法可以枚举这两个序列的所有交集吗?
一个64位的数字P在这两个序列的交集中,如果P % k == 0,并且(P & C) == C,并且(P & ~(C | m)) = 0。
注意:枚举第二个序列实际上非常容易。
uint64_t m = ..., C = ...;
uint64_t subset = 0;
do {
uint64_t value = subset + C;
print(value);
// if (value % 5) => in the intersection of the sequences
subset = (subset - m) & m;
} while (subset != 0);
编辑:枚举的顺序并不重要。
另外:我并不完全希望列举出所有的交集,但我想要一个可以始终前进并获取下一个交集的迭代器。
k == 2
和m == ~0
,大约一半的64位数字在交集中。即使以某种方式发现下一个成员只需O(1)
的时间,打印它们所有将需要几乎永远的时间。是否有关于k
、m
和/或C
的限制,使得完整枚举合理;或者进一步处理结果以使完整枚举变得不必要?如果你不介意我问的话,这个练习的最终目标是什么? - Igor Tandetnikk==2
和m == ~0
,大约一半的64位数字都在交集中。即使以某种方式仅需O(1)
的时间来发现下一个成员,打印它们全部将需要几乎永远的时间。是否有关于k
、m
和/或C
的限制,使得完全枚举变得合理;或者有进一步处理结果的方法,使得完全枚举变得不必要?如果你不介意我问的话,这个练习的最终目标是什么? - Igor Tandetnik(subset - m) & m
。我只是想构建一个迭代器,让我能够轻松地发现下一个交集,我并没有真正希望遍历所有的交集。 - Null(subset - m) & m
。我只想构建一个迭代器,让我能够轻松地发现下一个交集,我并没有真正希望遍历所有的交集。 - Null