我试图找到一列出现不止一次的位。让我举一个例子:
X Y Z Set A 0 1 0 Set B 0 0 1 Set C 0 1 0 Set D 0 0 0
通过UNION操作,我可以知道集合列表中的哪个COLUMN的位设置为1。如果我执行UNION B UNION C UNION D,则得到 0 1 1 ,这意味着X列的位没有设置为1,Y列和Z列的位中至少有1位设置为1。
我的问题是我试图找到正确的设置操作,以查找将位设置为1以上的列。在上面给出的示例中,列Y的2位设置为1。因此结果应为 0 1 0 。
我尝试做交叉路口,这是最合乎逻辑的事情,但是会产生不同的结果。
我很高兴有人可以指导我应该执行哪种设置操作组合以获得理想的结果。预先感谢。
答案 0 :(得分:1)
我的问题是我试图找到正确的set操作来查找将位设置为1以上的列。
这是一种方法:
(A∩B)∪(A∩C)∪(A∩D)∪(B∩C)∪(B∩D)∪(C∩D)
也就是说,数学非常灵活;您可以从字面上说“包含至少出现在两个集合 A , B , C ,中的所有元素的集合D ”,并且数学家会出于大多数目的接受它。
答案 1 :(得分:0)
让 select * from events
where (min_age <= 11 AND max_age >= 11)
OR (min_age <= 13 AND max_age >= 13)
OR (min_age <= 16 AND max_age >= 16)
和USet_0 := 0 0 0
。然后我们定义
DSet_0 := 0 0 0
和
USet_(k+1) := USet_k UNION Set_k | forall 0 <= k < n
找到所有DSet_(k+1) := DSet_k UNION (USet_k INTERSECT Set_k) | forall 0 <= k < n
集的并集的操作将产生n
。然后,具有多位设置的任何列都由USet_n
表示。
答案 2 :(得分:0)
当您尝试有效地进行操作时,这会更加有趣。
从0开始按顺序将数字分配给每个集合。
然后,如果存在至少两个不同集合中的一列,则这两个集合的编号必须不同;如果数字不同,则这些数字的二进制表示形式将至少一个不同位位置。
所以:
对于集合编号中每个位的位置 b (有对数(集合的个数)):
创建所有在其编号中设置了 b 位的集合的并集;
创建所有没有在其编号中设置了 b 位的集合的并集;
将这两个集合相交。
创建所有这些交叉点的并集。
完成。结果是出现在至少2个不同集合中的所有列的集合。
例如,如果列在集合 5 和集合 7 中,则列将在位位置 b = 1 (位置值2),因为 5 (101)和 7 (111)的二进制表示形式是在那个位的位置不同。该列将位于所有具有 1 位关闭的数字的并集内,而和则位于具有 1 位的所有集合的并集内上。
所需的设置操作总数为 N * log(N),其中 N 是设置数量。