Batman
Batman

Reputation: 1324

What does the following code do?

i = i + j ;
j = i - j ;
i = i - j ;

What the above code do ? Can someone write the same operation with other code ?

thnx.

Upvotes: 5

Views: 869

Answers (10)

Margus
Margus

Reputation: 20038

Temporary variable swap

And most used swap method involves using a temporary variable:

T swap = i;
i = j;
j = swap;
swap = null; // or let it fell out of scope

Aritmetical swap

i = i + j ;
j = i - j ; // i + j - j = i
i = i - j ; // i + j - (i + j - j) = j

This hack only works if:

  • i and j are integers and their sum is between 2147483647 and -2147483648.
  • i and j are longs and their sum is between 9223372036854775807 and -9223372036854775808.

xor swap

There is a similar xor swap hack

i = i ^ j;
j = i ^ j; // i ^ j ^ j = i
i = i ^ j; // i ^ j ^ i ^ j ^ j = j

And it's slight variation of:

a[i] = a[i] ^ a[j];
a[j] = a[i] ^ a[j]; 
a[i] = a[i] ^ a[j]; 

This hack only works if:

  • i != j, two indexes refer to the same element and thy cancel each-other out.

Upvotes: 6

Jacob Barnard
Jacob Barnard

Reputation: 11

Assuming i and j are numeric primitives, assuming the operators operate like they do in Java, C++, or the like, and assuming the operators have not be redefined, then we can look at this line of code like this:

i = i + j;
j = i - j;
i = i - j;

Here, i becomes the sum of the two variables. In the second line of code though, we remove j from that sum and assign it to j. We can therefore reduce the first two lines to the following:

j = i;

Variable j now equals our original i. But currently, i doesn't have the same value it started with. Right now, i is equivalent to the sum of the original two values. In the next line of code, we say:
i = i - j, which in pseudocode is equivalent to:
i = originalSum - originalValueOf_i; //The original j.

So, basically, all of the original code is equivalent to a swapping routine, i.e.:

tempVal = i;
i = j;
j = tempVal;


We can even try an example involving positive and negative values to see that this is true:

i = -24.3;
j = 10.4;
//Original code:
i = i + j; //i now equals -13.9
j = i - j; //j now equals -13.9 - 10.4, which is -24.3 (our original i value).
i = i - j; //i now equals -13.9 - (-24.3), which is 10.4 (our original j).


Someone may have written the swap you posted in the way he/she did to avoid method call overhead, declaring new variables, etc., but if you're going to be swapping values a lot, using the code you posted over and over could get icky. A swap routine like the one shown above is fairly common.

Upvotes: 1

Dbz
Dbz

Reputation: 2761

It's a technique to swap the values of i and j without creating a temporary variable. It's a form of memory optimization

If you're interested in learning about some of these things, I found a site about swapping values:

http://booleandreams.wordpress.com/2008/07/30/how-to-swap-values-of-two-variables-without-using-a-third-variable/

Another way to swap values is with the bitwise operator Exclusive Or (XOR)

a = a ^ b

b = a ^ b

a = a ^ b

This way is my favorite personally because it's more fun to think about conceptually. Integers are sets of bits, (ones and zeros)

a 64 bit integer has 64 "ones and zeros"

The ones and zeros are binary.

1 = 1

10 = 2

11 = 3

100 = 4

101 = 5

111 = 6

That's an example of binary to decimal. Now the bitwise operator XOR works like flipping a switch. So:

2 ^ 1 = 3 :binary: 10 ^ 01 = 11

and

3 ^ 2 = 1 :binary: 11 ^ 10 = 01 = 1

Now now that you understand that, you can see how swapping variables with it might work out.

Let's set a = 3 and b = 2 (in binary) and try it

a = 100

b = 10

a = a ^ b :: a = 100 ^ 10 = 110

b = a ^ b :: b = 110 ^ 10 = 100

a = a ^ b :: a = 110 ^ 100 = 10

now a = 10 and b = 100 or a = 2 and b = 3

Welcome to bits!

Upvotes: 14

user541686
user541686

Reputation: 210445

It swaps the variables.

Another way:

i ^= j;
j ^= i;
i ^= j;

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500465

It swaps them - but it's easier to tell this if you use different variable names to keep things clear:

int originalI = ...;
int originalJ = ...;

int tmp = originalI + originalJ;
int newJ = tmp - originalJ;
int newI = tmp - newJ;

Now perform substitutions:

int originalI = ...;
int originalJ = ...;

int tmp = originalI + originalJ;
int newJ = originalI + originalJ - originalJ;
int newI = originalI + originalJ - (originalI + originalJ - originalJ);

... and simplify:

int originalI = ...;
int originalJ = ...;

int tmp = originalI + originalJ;
int newJ = originalI;
int newI = originalJ;

... and remove the temporary variable:

int originalI = ...;
int originalJ = ...;

int newJ = originalI;
int newI = originalJ;

Upvotes: 2

unwind
unwind

Reputation: 399803

The obvious way to do this with other code would be:

const int tmp = i;
i = j;
j = tmp;

This assumes that the type is int. Note that this swap trick is not safe if there is integer overflow/underflow risks in the computations. It's also not very clear, people who read it need to think pretty hard to understand what's going on (or ask someone).

Upvotes: 3

Carl
Carl

Reputation: 7544

It switches the values of i and j:

i = i+j;
j = (original_i + j) - j = original_i;
i = original_i + original_j - original_i = original_j;

Yes, there are other ways to do this operation.

Upvotes: 0

Cu7l4ss
Cu7l4ss

Reputation: 566

i gets j's value. And j keeps it's value.

Upvotes: 0

Andrzej Doyle
Andrzej Doyle

Reputation: 103797

It swaps i and j. Assuming they have initial values of a and b, the lines evaluate to:

i = a + b;
j = (a + b) - b; // = a
i = (a + b) - a; // = b

To answer the second part of your question, an alternative (and more than likely, the approach that would be taken in real life, non-interview situations) would look something like the following:

int tmp = i;
i = j;
j = tmp;

Upvotes: 12

Daniel A. White
Daniel A. White

Reputation: 190945

It looks like its swapping i and j.

Upvotes: 1

Related Questions