Swapping two variable value without using third variable

Viewed 124109

One of the very tricky questions asked in an interview.

Swap the values of two variables like a=10 and b=15.

Generally to swap two variables values, we need 3rd variable like:

temp=a;
a=b;
b=temp;

Now the requirement is, swap values of two variables without using 3rd variable.

30 Answers

Swapping two numbers using third variable be like this,

int temp;
int a=10;
int b=20;
temp = a;
a = b;
b = temp;
printf ("Value of a", %a);
printf ("Value of b", %b);

Swapping two numbers without using third variable

int a = 10;
int b = 20;
a = a+b;
b = a-b;
a = a-b;
printf ("value of a=", %a);
printf ("value of b=", %b);
#include<iostream.h>
#include<conio.h>
void main()
{
int a,b;
clrscr();
cout<<"\n==========Vikas==========";
cout<<"\n\nEnter the two no=:";
cin>>a>>b;
cout<<"\na"<<a<<"\nb"<<b;
a=a+b;
b=a-b;
a=a-b;

cout<<"\n\na="<<a<<"\nb="<<b;
getch();
}

Of course, the C++ answer should be std::swap.

However, there is also no third variable in the following implementation of swap:

template <typename T>
void swap (T &a, T &b) {
    std::pair<T &, T &>(a, b) = std::make_pair(b, a);
}

Or, as a one-liner:

std::make_pair(std::ref(a), std::ref(b)) = std::make_pair(b, a);

If you change a little the question to ask about 2 assembly registers instead of variables, you can use also the xchg operation as one option, and the stack operation as another one.

#include <stdio.h>

int main()
{
    int a, b;
    printf("Enter A :");
    scanf("%d",&a);
    printf("Enter B :");
    scanf("%d",&b);
    a ^= b;
    b ^= a;
    a ^= b;
    printf("\nValue of A=%d B=%d ",a,b);
    return 1;
}

The best answer would be to use XOR and to use it in one line would be cool.

    (x ^= y), (y ^= x), (x ^= y);

x,y are variables and the comma between them introduces the sequence points so it does not become compiler dependent. Cheers!

Maybe off topic, but if you know what you are swapping a single variable between two different values, you may be able to do array logic. Each time this line of code is run, it will swap the value between 1 and 2.

n = [2, 1][n - 1]

You could do:

std::tie(x, y) = std::make_pair(y, x);

Or use make_tuple when swapping more than two variables:

std::tie(x, y, z) = std::make_tuple(y, z, x);

But I'm not sure if internally std::tie uses a temporary variable or not!

In javascript:

function swapInPlace(obj) {
    obj.x ^= obj.y
    obj.y ^= obj.x
    obj.x ^= obj.y
}

function swap(obj) {
    let temp = obj.x
    obj.x = obj.y
    obj.y = temp
}

Be aware to execution time of both options.

By run this code i measured it.

console.time('swapInPlace')
swapInPlace({x:1, y:2})
console.timeEnd('swapInPlace') // swapInPlace: 0.056884765625ms

console.time('swap')
swap({x:3, y:6})
console.timeEnd('swap')        // swap: 0.01416015625ms

As you can see (and as many said), swap in place (xor) take alot time than the other option using temp variable.

R is missing a concurrent assignment as proposed by Edsger W. Dijkstra in A Discipline of Programming, 1976, ch.4, p.29. This would allow for an elegant solution:

a, b    <- b, a         # swap
a, b, c <- c, a, b      # rotate right

How about,If we do with parallel processing with "GO" lang..

var x = 100; var y = 200;

swap1 := func(var i) { x = i } swap2 := func(var y) { y = i } Parallelize(swap1, swap2)

In awk, without needing a temp variable, a temp array, an external function call, substring-ing their values out of one another, XOR operations, or even any math operations of any sort,

this trick works for whether their values are numeric, string, or even arbitrary bytes that aren't UTF8-compliant, nor do the types of the 2 variables even need to match :

      gawk/mawk/nawk '{ 
                       a = (b) \
          substr("", ( b = (a) )^"")
      }'

Even in Unicode-locale, gawk unicode mode could swap the values of arbitrary non-UTF8 bytes without any error messages.

No need to use C or POSIX locale.

Why it works is that in the process of this concatenation, the original value of b has already been placed in some system-internal staging ground, so the sub-sequent assignment of b's value into a does not have any impact into what's being assigned into a

The second half of it is taking a substring of an empty string, so of course nothing comes out, and doesn't affect the first half.

After b = a, I immediately take the zero-th power of it, which always returns a 1 in awk

so the latter portion becomes

  # in awk, string indices start from 1 not 0
  
  substr(EMPTY_STRING, STARTING-POSITION-OF-ONE) 
  

of course nothing comes out of it, which is the desired effect, so the clean original value of b could be assigned into a.

This isn't taking a substring of a's or b's value. It's taking advantage of dynamic typing properties of awk.

A XOR-based approach, which clean, still require 3 operations, plus a safety check against being memory position (for C). And for gnu-awk, its xor() function only works with non-negative numeric inputs.

This one-liner approach circumvents all the common issues with value swapping.

Either a or b, or even both, being an array cell, regardless of single or multi-dimensional, e.g.

arr[ _pos_idx_a_ ]

works exactly the same with this one-liner approach. The only limitation I could think of is that this approach cannot directly swap full contents of an entire array with another array.

I thought of adding a check for a==b to avoid a double assignment, but then realized the internal system resources needed to perform such a check is not worth the minuscule amount of time saved.

Try this code: (sample in php)

$a = 5;
$b = 7;
 echo $a .' ***Before*** '. $b;
$a = $a + $b; //12
$b = $a - $b; //12 - 7 = 5
$a = $a - $b; //12 - 5 = 7
 echo $a .' ***After*** '. $b;
Related