Algorithm 异或运算算法

Algorithm 异或运算算法,algorithm,xor,Algorithm,Xor,我想用从0到(n)^{1/2}-1的每个数字计算从0到(n)^{1/2}-1的数字的异或。 我想在O(n)时间内完成此操作,但不能使用XOR、OR和运算 如果我知道X和Y的XOR,我能在恒定时间内计算X+1和Y的XOR吗 正如一些人指出的那样,XOR可以在恒定时间内使用AND和NOT进行计算。 如何为和执行相同的操作? 如何计算从0到(n)^{1/2}-1的数字的和,以及从0到(n)^{1/2}-1的每个数字。 我想在O(n)时间内完成此操作,但不能使用XOR、OR和运算 这里假设的是RAM模型

我想用从0到(n)^{1/2}-1的每个数字计算从0到(n)^{1/2}-1的数字的异或。 我想在O(n)时间内完成此操作,但不能使用XOR、OR和运算

如果我知道X和Y的XOR,我能在恒定时间内计算X+1和Y的XOR吗

正如一些人指出的那样,XOR可以在恒定时间内使用AND和NOT进行计算。 如何为和执行相同的操作? 如何计算从0到(n)^{1/2}-1的数字的和,以及从0到(n)^{1/2}-1的每个数字。 我想在O(n)时间内完成此操作,但不能使用XOR、OR和运算


这里假设的是RAM模型,对您可以从NAND(图)构建异或门,因此您可以使用
if
语句和
实现异或门
(NOT)和
&&
和(如果我们在这里使用C/C++/PHP作为示例)。至于在一个恒定的时间内计算出来,每次迭代的计算都是相同的,因此它将是恒定的。

可以使用AND和NOT构建XOR(并将它们结合起来构建NAND)。你能用和不用吗

在C#中:

Func nand=(p,q)=>!(p&q);
Func xor=(p,q)=>
{
var s1=nand(p,q);
var s2a=nand(p,s1);
var s2b=nand(q,s1);
返回nand(s2a、s2b);
};
我在模仿这个:

在C#中,使用模,求和和和乘法。 (限制:我使用的是uint,最多32位。它适用于ulong,最多64位)

uint a=16;
uint b=5;
uint mult=1;
uint-res=0;
对于(int i=0;i<32;i++)
{
uint i1=一个%2;
uint i2=b%2;
如果(i1!=i2){
res+=mult;
}
a/=2;
b/=2;
mult*=2;
}
其中res是响应

模数可以建立在除法、乘法和减法的基础上。

是的

从[1x1]网格开始:

H(-1) = [ 0 ]
然后应用递归:

H(i) = [ H(i-1)           H(i-1)+(1 << i)
         H(i-1)+(1 << i)  H(i-1)          ]

H(i)=[H(i-1)H(i-1)+(1首先,让k是大于或等于sqrt(n)的2的最小幂。k仍然是O(sqrt(n)),因此这不会改变复杂性

为了构造完整的k×k表,我们一次构造一行

我们从第0行开始:这很简单,因为0 xor j=j

for i in xrange(k):
    result[0][i] = i
接下来,我们按格雷码顺序检查行。格雷码是一种通过每次改变一位来计算从0到小于2的幂的每一个数字的方法

由于格雷码特性,我们将行数更改1位,因此我们可以轻松地从旧行计算新行,因为XOR只更改1位

last = 0
for row in graycount(k):
    if row == 0: continue
    bit_to_change = find_changed_bit(last, row)
    for i in xrange(k):
        result[row][i] = flip_bit(result[last][i], bit_to_change))
    last = row
我们需要一些函数来帮助我们,首先是一个找到不同的第一位的函数

def find_changed_bit(a, b):
    i = 1
    while True:
        if a % 2 != b % 2: return i
        i *= 2
        a //= 2
        b //= 2
我们需要一个在O(1)时间内稍有变化的函数

最后是棘手的一点:用格雷码计数。从维基百科上,我们可以看到一个简单的格雷码可以通过计算xor(a,a//2)得到


请注意,slow_xor是O(a和b中的位数),但这里没有问题,因为我们没有在主函数的内环中使用它。

如果两者不相等,则它们是xor

xorBits(bit1,bit2){
     return bit1 != bit2?1:0
}

xorBooleans(boolean1,boolean2){
    return boolean1 != boolean2
}

为什么不能使用异或?你可以使用什么运算符来代替?这是“家庭作业”吗?如果是,你应该相应地标记它。输出包含O(n.log(n))位,因此无法在O(n)时间内生成。@Paul:输出怎么能包含O(n log n)位?它处理的最大数字是根n…@Jon root n包含日志(根n)=log(n) /2位。输出是一个由sqrt(n)*sqrt(n)个数字(即,n个数字)组成的表,每个数字都有O(logn)位。我认为关键是这种方法一次计算一位结果。输出矩阵中有n.log(n)位,所以这不是O(n).回答很好。我找到了一种更复杂的方法。@xanatos:是的,它能用!我怀疑它有名字!这里真的没有什么神奇的地方;我只是为每个位独立计算XOR函数,然后将结果分布到输出数组中的所有位置。(如果重写
H(I-1)
as
H(i-1)+(0如果有人不喜欢我的回答,我没有任何问题,但给我-1的人至少应该告诉我我做错了什么。是的,我知道我的答案不是完美的,但考虑到OP可能会问一个“学术”或“家庭作业”问题,我认为答案不一定是正确的“世界上最美的”问题是你的解决方案没有正确回答这个问题。你用一点一点的方法实现了xor,产生了一个O(n.log(n))解决方案。问题是找到一个O(n)解决方案(尽管无可否认,这个问题的措辞不是特别清楚)。@Paul对def find_changed_bit(a, b):
    i = 1
    while True:
        if a % 2 != b % 2: return i
        i *= 2
        a //= 2
        b //= 2
def flip_bit(a, bit):
    thebit = (a // bit) % 2
    if thebit:
        return a - bit
    else:
        return a + bit
def graycount(a):
    for i in xrange(a):
        yield slow_xor(a, a // 2)

def slow_xor(a, b):
    result = 0
    k = 1
    while a or b:
        result += k * (a % 2 == b % 2)
        a //= 2
        b //= 2
        k *= 2
    return result
xorBits(bit1,bit2){
     return bit1 != bit2?1:0
}

xorBooleans(boolean1,boolean2){
    return boolean1 != boolean2
}