How does Xor work in swapping values? - java

Here is the original code:
public static String reverseString(String s){
if(s == null) return "";
char[] rev = s.toCharArray();
int i = 0, j = s.length() - 1;
while(i < j) {
rev[i] ^= rev[j];
rev[j] ^= rev[i];
rev[i++] ^= rev[j--];
}
return String.valueOf(rev);
}
My question is how does Xor work in swapping character values here, and why is rev[i++]^=rev[j--] needed here?

The code is equivalent to
rev[i] ^= rev[j];
rev[j] ^= rev[i];
rev[i] ^= rev[j];
i++; j--;
The last part is just needed to increment i and decrement j for the next loop iteration.
As to why x ^= y; y ^= x; x ^= y works to swap the values, I don't know why, but you can see that it works on 1-bit values by look at all four possibilities:
start after x^=y after y^=x after x^=y
x y x y x y x y
0 0 0 0 0 0 0 0
0 1 1 1 1 0 1 0
1 0 1 0 1 1 0 1
1 1 0 1 0 1 1 1
So you can see that in all cases, the x and y bits are swapped. When the statements are applied to larger integers, the ^ operator works on all bits in parallel, so the end result is that every pair of bits is swapped, i.e. the entire values are swapped.

XOR operator has this very unique operator that it acts as inequality detector meaning only when the two bits differ result will be 1 else result is 0.
Now take this for example say in A^B, ith bit 1, this means that ith bit of A and B differ. Meaning one of them is 1 and the other is 0.
Now when we do this (A^B)^B , if the ith bit in B was 0, what we will get is 1 since 1^0 = 1, which is equal to ith bit in A and (A^B)^A = 0, which is ith bit in B.
Similarly,When ith bit is B is 1 and in A is 0, again swapping occurs.
Same logic applies to when ith bit in A^B is 0. You can veryify it very easily.
Its easy to see how the swapping is occurring, When you xor the original number with A^B, you get the other number, because swapping happens for each of the respective bits

The below routine is expected to swap the values of a and b
a = a ^ b
b = b ^ a
a = a ^ b
Let's analyze to see how and why the swap works.
For that, let's not swap the values, but store them in separate variables, so we can see what exactly goes on.
a0 = a ^ b
b1 = b ^ a0
a1 = a0 ^ b1
Simplifying the equations using below properties of XOR. Check XOR Properties#Wikipedia for reference
commutative (a ^ b == b ^ a)
associative (a ^ (b ^ c) == (a ^ b) ^ c)
a ^ a == 0
0 ^ a == a
a0 = a ^ b // Equation #1
b1 = b ^ a0
a1 = a0 ^ b1
b1 = b ^ a0 // Equation #2
= b ^ (a ^ b) // Using Equation #1
= b ^ (b ^ a) // Property #1
= (b ^ b) ^ a // Property #2
= 0 ^ a // Property #3
= a // Property #4
a1 = a0 ^ b1
= a0 ^ (b ^ a0) // Using Equation #2
= (a ^ b) ^ (b ^ (a ^ b)) // Using Equation #1
= (b ^ a) ^ (b ^ (b ^ a)) // Using Property #1
= (b ^ a) ^ ((b ^ b) ^ a) // Using Property #2
= (b ^ a) ^ (0 ^ a) // Using Property #3
= (b ^ a) ^ a // Using Property #4
= b ^ (a ^ a) // Using Property #2
= b ^ 0 // Using Property #3
= b // Using Property #4
As you can see, b1 now contains the original value of a and a1 contains the original value of b, i.e. the values of b and a are swapped
In summary, a^=b;b^=a;a^=b is just an idiomatic expression, nothing magical in it :)
Plain English explanation for the same
XOR sets the bits when the operand bits are dissimilar and resets the bits otherwise
Let's walk through the transformations that take place with an example. For that let's say, we have the following numbers (in binary) assigned to the variables.
a = 1 1 0 0
b = 1 0 1 0
Step #1: a = a ^ b // CREATE A MASK
a = 0 1 1 0
b = 1 0 1 0
Imagine the new value of a is a mask for generating the old value of a given b or generating the old value of b given a.
Step #2: b = b ^ a // Recover original value of a using mask and original value of b
a = 0 1 1 0
b = 1 1 0 0
Since b is still preserved/untouched, we can recover original value of a with the mask - which is what we did in this step
Step #3: a = a ^ b // Recover original value of b using mask and original value of a
a = 1 0 1 0
b = 1 1 0 0
Now we have the original value of a in variable b, so we can use our same mask to recover the original value of b. We can overwrite the mask now, since we don't need the mask after this step.

If you will agree that y == (x^y)^x == x^(y^x), then you have the answer.
Consider an abstract version of the loop body in the code you gave:
a = a ^ b
b = b ^ a
a = a ^ b
Now rename one value to clarify what's happening:
a_xor_b = a ^ b
b = b ^ a_xor_b // Now b is the original a because b^(a^b) == a!
a = a_xor_b ^ b // Now a is the original b because (a^b)^a == b!
Now note the code works fine if a_xor_b is the same variable is a.

It may be easier to first consider a different (but closely related) way of swapping two number values a and b:
a = a + b;
b = a - b;
a = -b + a;
This works both with pure arbitrary-precision numbers, and with integers modulo N (integers that wrap around when they get too big or small, like they do in Java).
To analyze this mathematically, we should assign a new symbol each time a value would change so that = can represent mathematical equality instead of assignment. Then, it is just a matter of basic algebra.
a1 = a0 + b0
b2 = a1 - b0 = (a0 + b0) - b0 = a0
a2 = -b2 + a1 = -(a0) + (a0 + b0) = b0
What about XOR? One way to explain XOR is to think of it as binary addition without carrying. Performing a swap with XOR is then equivalent to performing the "addition swap" described above on each bit modulo 2. The expression can be simplified, though, since in addition modulo 2, each number is its own inverse (equivalently, addition and subtraction are the same). This (with commutativity) gives us the familiar:
a = a ^ b;
b = b ^ a;
a = a ^ b;
In general, the "addition swap" above can be performed in any mathematical group (even if it is non-commutative -- basically just associativity and inverses are needed). Another way of thinking of XOR is just that it induces a group structure on the n-bit integers, and so swapping works just as it does in any group.

Related

How does xor give different number in two arrays‽

I have answered the following kata: Lost number in number sequence. The description is:
"An ordered sequence of numbers from 1 to N is given. One number might have deleted from it, then the remaining numbers were mixed. Find the number that was deleted.
Example:
The starting array sequence is [1,2,3,4,5,6,7,8,9]
The mixed array with one deleted number is [3,2,4,6,7,8,1,9]
Your function should return the int 5.
If no number was deleted from the array and no difference with it, your function should return the int 0.
Note that N may be 1 or less (in the latter case, the first array will be [])."
I have written a simple answer:
import java.util.*;
public class Kata {
public static int findDeletedNumber (int[] arr, int[] mixedArr) {
Arrays.sort(mixedArr);
for(int i = 0; i < arr.length; i++){
try{
if(arr[i] != mixedArr[i]){
return arr[i];
}
}catch(ArrayIndexOutOfBoundsException e) {
return arr[i];
}
}
return 0;
}
}
I was reading other people's answers and I found one which I find very hard to understand deeply:
import java.util.Arrays;
public class Kata {
public static int findDeletedNumber(int[] arr, int[] mixedArr) {
return Arrays.stream(arr).reduce((a, b) -> a ^ b).orElse(0) ^ Arrays.stream(mixedArr).reduce((a, b) -> a ^ b).orElse(0);
}
}
The link to the answer: https://www.codewars.com/kata/reviews/595be553429e11365c00006f/groups/59bef3a1eda42eb0bc001612
I would like to have some help, if anyone cares and have the patience to write an explanation and/or a trace, would be helpful. Currently I can see the answer but I do not understand it. 🤯
In addition I have tried to understand it by myself reading:
What does the ^ operator do in Java?
https://www.geeksforgeeks.org/bitwise-operators-in-java/
Truth table of XOR (Exclusive-OR)
X Y result
0 0 0
0 1 1
1 0 1
1 1 0
What means X^Y? Let´s look at an example, 5^6
dec bin
5 = 101
6 = 110
------------------ xor
3 = 011
XOR-ing two numbers is just converting the two numbers to binary and apply the rules in the truth table.
Looking at the table above, it is obvious that X^X = 0 for any integer X
5 = 101
5 = 101
------------------ xor
0 = 000
and X^0 = X
5 = 101
0 = 000
------------------ xor
5 = 101
Given your two arrays XOR-ing each element in both arrays and XOR-ing the result means something like
(1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 7 ^ 8 ^ 9) ^ (3 ^ 2 ^ 4 ^ 6 ^ 7 ^ 8 ^ 1 ^ 9)
and because X^Y = Y^X and X^Y^Z = (X^Y)^Z = X^(Y^Z) you can rearrange the above to
(1 ^ 1) ^ ( 2 ^ 2) ^ (3 ^ 3) ^ (4 ^ 4) ^ (5) ^ (6 ^ 6) ^ (7 ^ 7) ^ (8 ^ 8) ^ (9 ^ 9)
everything cancels each other out except for the missing number, i.e 5.

Meaning of << and |= in Java

There is a question of implementing a code in Java where I have to find if the string has unique characters or not without having to create a new data structure.
The Java implementation was as follows:
public static boolean isUniqueChars(String str) {
int checker = 0;
for (int i = 0; i < str.length(); ++i) {
int val = str.charAt(i) - 'a';
if ((checker & (1 << val)) > 0) return false;
checker |= (1 << val);
}
return true;
}
In line 5-6, there's the << that I don't really get.
And in line 6, I don't get what the '|' symbol does.
Could someone give a brief explanation of how this code works?
Thanks.
1. For this symbol : <<
In your code : 1 << val means (int)Math.pow(2,val) = 2 ^ val
2. For this symbol : >>
>> is bit-shift operator
x >> N means (if you view it as a string of binary digits):
The rightmost N bits are discarded
The leftmost bit is replicated as many times as necessary to pad the result to the original size (32 or 64 bits),
e.g.
00000000000000000000000000101011 >> 2 -> 00000000000000000000000000001010
11111111111111111111111111010100 >> 2 -> 11111111111111111111111111110101
3. For this symbol : |=
it means bitwise inclusive OR and assignment operator
E.g:
checker |= (1<<val)
is same as checker |= (2^val)
is same as checker = checker | (2^val) (*)
then : A | B ( | means Binary OR Operator copies a bit if it exists in either operand)
Example
A = 00101010
B = 01101000
A | B = 01101010
with
0 OR 0 = 0 , 1 OR 0 = 1
1 OR 1 = 1 , 0 OR 1 = 1
Using Ziprox's helpful hint that (1 << val) is equivalent to 2^val or Math.pow(2,val). It becomes much easier to decipher what is happening.
I believe 'int' is 4 bytes long which is 32 bits. This method is converting each letter in the alphabet (undercase) to number 2 ^ val. Basically, each letter is represented by a unique bit of the variable checker. 26 letters, 32 bits gives you 6 extra bits that do nothing.
checker & (1<<val)
will only be true of it has seen the number previously.
checker |= (1<<val)
is equivalent to
checker = (checker | (1<<val))
which simply flips that letter's bit from 0 to 1 to indicate that it has been seen.

What does ^= mean in Java?

I have seen the following code in HashMap.java.
h ^= k.hashCode();
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
A few random inputs produced an output similar to addition, but following code resulted in 0
int p = 10;
p ^= 10;
System.out.println("_______ " + p);
The ^= operator does an XOR with the variable on the left and the operand, then does an assignment to that variable of the result.
XOR something with itself and you get zero. It is an efficient way to set a register to zero as it doesn't move any memory.
^ is known as XOR (Exclusive disjunction or exclusive or), a logical operator, which follows:
1 xor 1 = 0
1 xor 0 = 1
0 xor 1 = 1
0 xor 0 = 0
as p^=10 is equivalent to:
p = p ^ 10; or, p = p xor 10
with p = 10 your operation is simply: , (10 ^ 10), which will result in 0
^ is the symbol for a logical XOR (Exclusive OR).
When placed before an equals sign, this means 'XOR myself with the given value, and write the result back to myself'. a ^= value is the same as saying a = a ^ value.
It might make it clearer if done with other operators, such as add:
E.g:
int counter = 14;
// Add 20 to counter (could also be written counter = counter + 20):
counter += 20;
// Counter is now 34
It is a compound assignment operator in java:
x op= y is equivalent to x = x op y (loosely speaking, see above link).
For example:
x += y; is equivalent to x = x + y;
x -= y; is equivalent to x = x - y;
and so on ...
For reference, this is the complete list of all such operators in java:
+= -= *= /= &= |= ^= %= <<= >>= >>>=
^= is bitwise exclusive OR and assignment operator. x ^= 2 is same as x = x ^ 2.

Java: Prefix - Postfix issue

I have a small issue performing a subtraction on numbers using prefix and postfix operators.
This is my program:
public class postfixprefix
{
public static void main (String args[])
{
int a = 5;
int b;
b = (a++) - (++a);
System.out.println("B = " +b);
}
}
Doing this, theoretically I am supposed to get 0 as the answer, but however, I am getting a -2.
When I try to individually try to increment the values like in this program:
public class postfixprefix
{
public static void main (String args[])
{
int a = 5;
int b, c;
b = a++;
c = ++a;
System.out.println("B = " +b);
System.out.println("C = " +c);
}
}
I get the values as B = 5, C = 7.
So i get the idea that 'c' takes the value of 'a' from 'b' (Please correct me if i am wrong), but what I want to know is
How can I have it not take the value of 'a' from 'b', and
using prefix - postfix, can I have 0 as an answer when they're subtracted.
If you go through this step by step, you can see what happens:
b = (a++) - (++a); //a is now 5
b = 5 - (++a); //read a, then increment it. a is now 6
b = 5 - 7; //increment a, then read it. a is now 7
b = -2
If you do it the other way, you get:
b = (++a) - (a++); //a is now 5
b = 6 - (a++); //increment a, then read it. a is now 6
b = 6 - 6; //read a, then increment it. a is now 7
b = 0
b = a++;
means:
assign to b the value of a
increase a by 1
c = ++a
means:
increase a by 1
assign to c the value of a
b = (a++) - (++a)
means:
get the value of a (5) (a without the ++)
increase the value of a by 1 (thus making it 6) (the result of a++)
increase a by 1 (++a) (thus making it 7)
assign to b thae value 5-7=-2 (5 from step 1, 7 from step 3)
So i get the idea that 'c' takes the value of 'a' from 'b' (Please correct me if i am wrong), but what I want to know is 1) How can I have it not take the value of 'a' from 'b'
Its not like this, in c = ++a; value is taken from a only, in b = a++; statement, a was incremented but after assigning value to b, and then while c = ++a; a is again incremented and assigned to c (as this is pre-increment now)
2) using prefix - postfix, can I have 0 as an answer when they're subtracted.
you can have like: b = (++a) - (a++); as first a increments first and then the second a (which is now 6) is substracted from first a (still 6). And then the final value of a is 7
int a = 5;
int b, c;
b = a++;
c = ++a;
About this code b has a value 5 because posting fix increment/decrement happens after assingment is completed. So the value is 5.
c has a value 7 because prefix increment/decrement happens before assingment is completed. So the value is 7 beause previous statement made the value of a as 6.
About this code
int a = 5;
int b;
b = (a++) - (++a);
System.out.println("B = " +b);
when brackets are applied, your prefix/postfix operations will be completed first in (a++) - (++a); from left to right fashion.
So firstly if we go left to right
(a++) -(++a)
1. (a++) -- Take 5 from a.
2. (++a) -- 5 becomes 6 with ++a take 6.
3. (a++) - (++a) -- Subtract results of (a++) - (++a) operations which makes it -2.
Solutions for you first query -- How can I have it not take the value of 'a' from 'b', and
int a = 5;
int temp = a;
int b, c;
b = a++;
c = ++temp;
System.out.println("B = " +b);
System.out.println("C = " +c);
**Solutions for you first query has been well explained by Sir #Keppil **

Swap in array, sorting proramm [duplicate]

This question already exists:
Wtat does it mean "^=" [duplicate]
Closed 7 years ago.
I have this peace of code in wiki page about sorting.
I suppose it has to swap to array elements, but can somebody explain it properly
array[i] ^= array[i-1];
array[i-1] ^= array[i];
array[i] ^= array[i-1];
wiki page https://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D1%88%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC
That is a way of swapping array[i] and array[i-1].
^= does a bitwise XOR between the two arguments and assigns it to the left one.
To see how that causes a swap lets consider just a pair of bits : A and B which contain values x and y respectively .
Before starting we have :
A = x
B = y
First instruction A^=B means A = ( A XOR B ) So we end up with :
A = x XOR y
B = y
Second instruction B^=A means B = ( B XOR A) So we end up with :
A = x XOR y
B = y XOR ( x XOR y )
Third instruction A^=B means A = ( A XOR B) So we end up with :
A = (x XOR y ) XOR ( y XOR ( x XOR y ) )
B = y XOR ( x XOR y )
Making use of the associativity and conmutativity of XOR we can reorder the previous operations as :
A = (x XOR x) XOR (y XOR y) XOR y
B = (y XOR y) XOR x
Making use of the property that a bit XOR itself is always 0 :
A = 0 XOR 0 XOR y
B = 0 XOR x
Making use the property that 0 XOR a bit is always the same bit :
A = y
B = x
As you can see A and B have been swapped.

Categories

Resources