Swap in array, sorting proramm [duplicate] - java

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.

Related

Tricky basic java operations [duplicate]

This question already has answers here:
How do the post increment (i++) and pre increment (++i) operators work in Java?
(14 answers)
Closed 3 years ago.
I got these 2 different codes in Java that I can't understand how they produce these specific outputs.
They seemed to work in 2 different logic and I can't figure it out!
int a = 5;
int b = 4;
a -= (b++) + ++a; // For more confusing results replace -= with += and see how the logic changes.
System.out.println(a); // Output: -5
and
int c = 8;
c += ++c;
System.out.println(++c); // Output: 18
How does each situation work and how are they producing these specific outputs?
The major difference here is what post and pre increment are. These determine whether the value is increased before evaluation, or afterward.
Here is how the first case breaks down mathematically:
a = 5 - (4 + 6), which reduces to -5.
Note that a is increased from ++a AKA preincrement before the math is done, however b is calculated as 4. Another thing to note is the a used from the -= uses the original a value, regardless of post or pre increment.
The second equation reduces to this mathematically:
c = 8 + 9 which reduces to 17.
The output prints 18 because your System.out.print(++c) increments it one more time before output due it being preincrement. Note if the print statement used c++, the value would print to 17.
The chart for operator precedence can be found here. Note that assignment has lower precedence than the unary/postfix operators.
It's all about the Operator Precedence in Java. Check that table and figure out which operation takes place first and which last.
It is equivalent to:
int a = 5;
int b = 4;
a -= (b++) + ++a; // => 5 -= (4) + 6
int c = 8;
c += ++c; // => 9 += 9
The main diff is thet:
++a and ++c increments the value and immediately returns it.
b++ returns the value and then increments it.
There is a difference in the order of ++. While both increase the variable, ++a will pass the original value to the operation chain your in middle of; while a++ would pass the new value. So for your first example:
++a --> a is now 6; but the equation is using 5:
a -= (b++) + 5;
b++ --> b is now 5;
a -= 5 + 5;
a -= 10;
? = 5 - 10;
a = a - 5 + 5;
a = 5 - 5 + 5;
a = -10;
(You should have enough to trace the second example).
For a list of operations try this. Some more increment examples are here.
A minimal example is `
int x=3,y=3;
x += ++x;
y+= y++;
at the x x is 7 and y is 6. Precedence alone is not enough to explain the behaviour. Using precedence the second line would be x += (++x), i.e. increment x and return its value, (x is now 4); next we have x+=4 which would return 8.
Instead, it seems better to treat x += w as a short hand for x = x + w, this rewriting happens before evaluation. In our case the rewriting is x = x + ++x interpreted as x = (x + (++x)). So interpreted as
x = ( 3 + (++x))
x = ( 3 + 4 ) x is 4
x = 7 x is 7
A simlar system works to the y equation giving y = 6 at the end.

How does Xor work in swapping values?

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.

Java Non Arithmetical Adder [duplicate]

This question already has answers here:
Performing arithmetic operations in binary using only bitwise operators [duplicate]
(2 answers)
Closed 8 years ago.
I found some code to add two numbers using XOR and AND without using any arithmetical operators.
I understand that x^y equates to the sum and that x&y equates to the carry. However I don't understand why the carry must be left shifted? My knowledge of the left bitwise shift is that is the same as multiplying by two. Why is the carry being multiplied by two?
public static int add(int x, int y) {
// Iterate till there is no carry
while (y != 0)
{
// carry
int carry = x & y;
// Sum
x = x ^ y;
y = carry << 1;
}
return x;
}
Any guidance appreciated.
Lets try with two small integer x=5 which binary equivalent is 101 and y=1, which binary equivalent is 001.
Now, why I am talking about binary or more specifically, want to deal with bits? Because XOR is a bit wise operation.
So, if you run XOR operation between x and y, the result is following:
x = x^y = 101 ^ 001 = 100 (decimal :4)
See, just XOR operation between two numbers don't give us the sum. (sum of 5 and 1 should be 6, not 4) We use the carry, to get the exact sum. Actually, the algorithm is designed in a way, so that it gives us the correct answer.
Now, lets see, how using carry in this algorithm, gives us the correct answer.
Since,
carry = x & y = 101 & 001 = 1 (decimal 1)
According to your program, y = carry << 1;
So, y will now become = 001 << 1 = 010 (decimal :2)
The loop will keep running, until y becomes zero.
If you run the loop again (since y=2 and not zero)
x = x ^ y = 100 ^ 010 = 110 (decimal :6)
carry = x & y= 100 & 010 = 0 (decimal 0)
Now, the XOR between the new value of x and y is 6 which is exactly the sum of 5 and 1. Look at carry, its value is now 0.
Our y will also become 0 now, because right shifting 0 will also give us 0. Since y is now zero, the loop will not run anymore and we got our sum by returning x!

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.

The difference between += and =+

I've misplaced += with =+ one too many times, and I think I keep forgetting because I don't know the difference between these two, only that one gives me the value I expect it to, and the other does not.
Why is this?
a += b is short-hand for a = a + b (though note that the expression a will only be evaluated once.)
a =+ b is a = (+b), i.e. assigning the unary + of b to a.
Examples:
int a = 15;
int b = -5;
a += b; // a is now 10
a =+ b; // a is now -5
+= is a compound assignment operator - it adds the RHS operand to the existing value of the LHS operand.
=+ is just the assignment operator followed by the unary + operator. It sets the value of the LHS operand to the value of the RHS operand:
int x = 10;
x += 10; // x = x + 10; i.e. x = 20
x =+ 5; // Equivalent to x = +5, so x = 5.
+= → Add the right side to the left
=+ → Don't use this. Set the left to the right side.
a += b equals a = a + b. a =+ b equals a = (+b).
x += y
is the same as
x = x + y
and
x =+ y
is wrong but could be interpreted as
x = 0 + y
It's simple.
x += 1 is the same as x = x + 1 while
x =+ 1 will make x have the value of (positive) one
Some historical perspective: Java inherited the += and similar operators from C. In very early versions of C (mid 1970s), the compound assignment operators had the "=" on the left, so
x =- 3;
was equivalent to
x = x - 3;
(except that x is only evaluated once).
This caused confusion, because
x=-1;
would decrement x rather than assigning the value -1 to it, so the syntax was changed (avoiding the horror of having to surround operators with blanks: x = -1;).
(I used -= and =- in the examples because early C didn't have the unary + operator.)
Fortunately, Java was invented long after C changed to the current syntax, so it never had this particular problem.
Because =+ is not a Java operator.

Categories

Resources