的差的和数提出溶液托比和马里奥实际上可以推广到任何其他数据类型,我们可以定义一个(恒定时间)二进制运算⊕是:Θ(n)⊕
- 总,使得对于任何值和b,一⊕ b被定义和相同类型的(或至少它的某些适当超型中,操作者对于其⊕仍然定义);aba⊕b⊕
- 缔合,使得 ;a⊕(b⊕c)=(a⊕b)⊕c
- 交换,使得 ; 和a⊕b=b⊕a
- 消,使得存在一个逆算子,其满足(一个⊕ b )⊖ b = 一个。从技术上讲,只要“减去”两个n个元素之和的耗时不超过O(n )个时间,该逆运算甚至不必一定是恒定时间。⊖(a⊕b)⊖b=anO(n)
(如果类型只能接受有限数量的不同值,则这些属性足以使它成为Abelian组;即使不是,它也至少将是可交换的可加 半组。)
使用这样的运算,我们可以将数组a = (a 1,a 2,… ,a n)的“和”定义为(⊕⊕a=(a1,a2,…,an)
(⊕a)=a1⊕a2⊕⋯⊕an.
给定另一个阵列
包含所有的元件
一个一个额外的元件加上
X,我们因此具有
(⊕b=(b1,b2,…,bn,bn+1)ax,所以我们可以通过计算发现这一额外的元件:
X = (⊕(⊕b)=(⊕a)⊕xx=(⊕b)⊖(⊕a).
例如,如果数组中的值是整数,则可以将整数加法(或对于有限长度整数类型进行模加)用作运算符,并将减法用作逆运算⊖。或者,对于任何其值可以表示为固定长度的位字符串的数据类型,我们可以将按位XOR用作⊕和⊖。⊕⊖⊕⊖
更一般地说,只要我们有某种方式可逆地删除末尾的填充,我们甚至可以将按位XOR方法应用于可变长度的字符串,方法是根据需要将其填充到相同的长度。
在某些情况下,这是微不足道的。例如,C样式的以null终止的字节字符串隐式地编码了它们自己的长度,因此对它们应用此方法很简单:对两个字符串进行XOR运算时,请用空字节填充较短的字符串以使它们的长度匹配,并修剪所有多余的尾随null最终结果。请注意,中间的XOR-sum字符串可以包含空字节,因此您需要显式存储它们的长度(但是最多只需要其中一个或两个)。
更一般而言,一种适用于任意位串的方法是应用一位填充,其中每个输入位串用单个位填充,然后根据需要匹配任意0位以匹配(填充)长度。最长的输入字符串。(当然,不需要预先明确地执行此填充;我们可以在计算XOR和时仅根据需要应用它。)最后,我们只需要从s中删除任何尾随的0位和最后1位即可。结果。或者,如果我们知道字符串最多为2 321001232字节长,我们可以将每个字符串的长度编码为32位整数并将其添加到字符串之前。或者,我们甚至可以使用一些前缀代码对任意字符串长度进行编码,然后将其添加到字符串之前。也存在其他可能的编码。
实际上,由于根据定义,可以在计算机上表示的任何数据类型都可以表示为有限长度的位字符串,因此该方法可得出该问题的通用解。Θ(n)
唯一可能棘手的部分是,要使取消生效,我们需要为每个值选择一个唯一的规范位串表示形式,如果可以给定两个数组中的输入值,则可能会很困难(实际上,甚至可能无法计算)。以不同的等效表示形式。但是,这不是此方法的特定弱点;如果允许输入包含等效性不确定的值,则解决此问题的任何其他方法也可能失败。