12

I came across a common programming interview problem: given a list of unsigned integers, find the one integer which occurs an odd number of times in the list. For example, if given the list:

{2,3,5,2,5,5,3}

the solution would be the integer 5 since it occurs 3 times in the list while the other integers occur even number of times.

My original solution involved setting up a sorted array, then iterating through the array: For each odd element I would add the integer, while for each even element I would subtract; the end sum was the solution as the other integers would cancel out.

However, I discovered that a more efficient solution existed by simply performing an XOR on each element -- you don't even need a sorted array! That is to say:

2^3^5^2^5^5^3 = 5

I recall from a Discrete Structures class I took that the Associate Property is applicable to the XOR operation, and that's why this solution works:

a^a = 0

and:

a^a^a = a

Though I remember that the Associative Property works for XOR, I'm having trouble finding a logical proof for this property specific to XOR (most logic proofs on the Internet seem more focused on the AND and OR operations). Does anyone know why the Associative Property applies to the XOR operation?

I suspect it involves an XOR identity containing AND and/or OR.

nickhar
  • 19,981
  • 12
  • 60
  • 73
Vilhelm Gray
  • 11,516
  • 10
  • 61
  • 114
  • 1
    You need consider only a single bit. XOR is addition modulo 2, and inherits associativity from addition of integers. Or just check the function table. – Daniel Fischer Nov 07 '12 at 14:05
  • Anyway, you can verify this by using truth tables. – md5 Nov 07 '12 at 14:09
  • When you have the proofs for the associativity of AND and OR, you can prove it for XOR using `a xor b = ¬((a and b) or (¬a and ¬b))` – harold Nov 07 '12 at 14:13
  • I don't understand why xor version would work. If the list is **{1,2,3,4}**, then 1^2^3^4 = ? – ylc Nov 07 '12 at 14:16
  • 1
    @ylc 4, but it's irrelevant, it solves the problem of "find the *one* integers that occurs an odd number of times", so a list that contains several numbers an odd number of times is outside the scope of the problem. – harold Nov 07 '12 at 14:20
  • @harold Oh, thanks to point it out. My bad. – ylc Nov 07 '12 at 14:27

2 Answers2

9

The associative property says that (a^b)^c = a^(b^c). Since XOR is bitwise (the bits in the numbers are treated in parallel), we merely need to consider XOR for a single bit. Then the proof can be done by examining all possibilities:

abc (a^b) (a^b)^c (b^c) a^(b^c)
000   0      0      0      0
001   0      1      1      1
010   1      1      1      1
011   1      0      0      0
100   1      1      0      1
101   1      0      1      0
110   0      0      1      0
111   0      1      0      1

Since the third column, (a^b)^c, is identical to the fifth column, a^(b^c), the associative property holds.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
1

As long as a ^ b == ~a & b | a & ~b, you can proove that :

(a ^ b) ^ c = ~((~a & b) | (a & ~b)) & c | ((~a & b) | (a & ~b)) & ~c

and

a ^ (b ^ c) = a & ~((~b & c) | (b & ~c)) | ~a & ((~b & c) | (b & ~c))

Are equals.

md5
  • 23,373
  • 3
  • 44
  • 93