如何有效地将XOR应用于两个整数数组?

时间:2017-07-11 10:03:33

标签: algorithm math mathematical-optimization

我有两个数组如下:

A = [1,2,35,4,32,1,2,56,43,2,21]
B = [1,2,35,4,32,1,2,56,43,45,1]

我们可以看到A和B的初始子序列相同,直到元素43.我的最终目标是计算这两个序列的最后不常见元素的XOR。在这里,我的目标是找到{2,21,45,1}的XOR。

目前,我的方法是将这两个数组的运行XOR存储在两个单独的数组中(例如,RESA [],& RESB []),然后当我被要求找到A的XOR时[0] -10]& B [0-9],我只是按如下方式快速执行单个XOR操作:

RESA[10] ^ RESB[9]

这是有效的,因为在XORing时,公共元素会被取消。

我的问题是,如果在每个查询中都传递了阈值T 。例如,在这种情况下,如果传递的阈值是32,则必须在A和B中过滤小于32的元素,然后对所有这些元素应用XORing。这肯定会增加复杂性,我无法应用我之前保持运行元素的XOR的逻辑。

如果您对如何利用XOR属性在没有阈值时像以前那样提出恒定时间方法有任何想法,请告诉我。

1 个答案:

答案 0 :(得分:2)

您已经通过计算两个数组中每个元素的XOR,找到了非常见元素的XOR。

XOR是一个可交换和关联的运算符,因此我们可以以任何我们喜欢的方式对数组进行重新排序,并且仍然具有相同的总XOR。

特别是,我们可以反向排序每个数组,然后计算每个排序数组的运行XOR。

通过这种预处理,我们现在可以通过对每个有序数组使用二进制搜索来计算高于阈值的所有元素的XOR,以查找T上方的元素数量,然后查找正在运行的XOR数组。

这为每个查询提供了O(logn)复杂度。

扩展

上述答案假设查询只是阈值32:即,开始始终为0,结束始终是每个序列的长度。 (我假设这是因为问题说最终目标是计算所有不常见元素的XOR。)

如果查询还包括要进行异或的区域的开始和结束,我建议采用另一种需要更多存储的方法(因为它需要对所有查询进行缓冲和排序):

  1. 按阈值对所有查询进行排序
  2. 维护每个序列的XOR的分段树,初始化为0。
  3. 按递减顺序将值添加到序列中,并在插入超过其阈值的所有值后立即执行查询。
  4. 例如,序列C = [1,2,35,4,32,1,2,56]的分段树将包含:

    1
    2
    35
    4
    32
    1
    2
    56
    1^2
    35^4
    32^1
    2^56
    1^2^35^4
    32^1^2^56
    1^2^35^4^32^1^2^56
    

    一旦我们得到这些值,我们就可以使用log(n)步骤计算任何范围的XOR。例如,假设我们想要计算C [1:3] = [2,35,4]的XOR。我们可以通过xoring 2 35 ^ 4来实现。