Zobaczmy prosty przykład w c, aby zamienić dwie liczby bez użycia trzeciej zmiennej.
program 1:
#include<stdio.h>
#include<conio.h>
main()
{
int a=10, b=20;
clrscr();
printf("Before swap a=%d b=%d",a,b);
a=a+b;//a=30 (10+20)
b=a-b;//b=10 (30-20)
a=a-b;//a=20 (30-10)
printf("\nAfter swap a=%d b=%d",a,b);
getch();
}
Wynik:
Przed zamianą a = 10 b = 20 Po zamianie a = 20 b = 10
Program 2: Używanie * i /
Zobaczmy inny przykład zamiany dwóch liczb za pomocą * i /.
#include<stdio.h>
#include<conio.h>
main()
{
int a=10, b=20;
clrscr();
printf("Before swap a=%d b=%d",a,b);
a=a*b;//a=200 (10*20)
b=a/b;//b=10 (200/20)
a=a/b;//a=20 (200/10)
printf("\nAfter swap a=%d b=%d",a,b);
getch();
}
Wynik:
Przed zamianą a = 10 b = 20 Po zamianie a = 20 b = 10
Program 3: Wykorzystanie bitowego operatora XOR:
Bitowy operator XOR może służyć do zamiany dwóch zmiennych. XOR dwóch liczb xiy zwraca liczbę, która ma wszystkie bity jako 1, gdziekolwiek bity x i y różnią się. Na przykład XOR z 10 (binarnie 1010) i 5 (binarnie 0101) to 1111, a XOR z 7 (0111) i 5 (0101) to (0010).
#include <stdio.h>
int main()
{
int x = 10, y = 5;
// Code to swap 'x' (1010) and 'y' (0101)
x = x ^ y; // x now becomes 15 (1111)
y = x ^ y; // y becomes 10 (1010)
x = x ^ y; // x becomes 5 (0101)
printf("After Swapping: x = %d, y = %d", x, y);
return 0;
Wynik:
Po zamianie: x = 5, y = 10
Program 4:
Nikt jeszcze nie zasugerował używania std :: swap.
std::swap(a, b);
Nie używam żadnych zmiennych tymczasowych iw zależności od typu aib implementacja może mieć specjalizację, która też nie. Implementację należy napisać, wiedząc, czy „sztuczka” jest odpowiednia, czy nie.
Problemy z powyższymi metodami:
1) Podejście oparte na mnożeniu i dzieleniu nie działa, jeśli jedna z liczb jest równa 0, ponieważ iloczyn staje się 0 niezależnie od drugiej liczby.
2) Oba rozwiązania arytmetyczne mogą powodować przepełnienie arytmetyczne. Jeśli x i y są zbyt duże, dodawanie i mnożenie może wyjść poza zakres liczb całkowitych.
3) Kiedy używamy wskaźników do zmiennej i dokonujemy zamiany funkcji, wszystkie powyższe metody zawodzą, gdy oba wskaźniki wskazują na tę samą zmienną. Zobaczmy, co się stanie w tym przypadku, jeśli oba wskazują na tę samą zmienną.
// Metoda oparta na bitowym XOR
x = x ^ x; // x becomes 0
x = x ^ x; // x remains 0
x = x ^ x; // x remains 0
// Metoda oparta na arytmetyce
x = x + x; // x becomes 2x
x = x – x; // x becomes 0
x = x – x; // x remains 0
Zobaczmy następujący program.
#include <stdio.h>
void swap(int *xp, int *yp)
{
*xp = *xp ^ *yp;
*yp = *xp ^ *yp;
*xp = *xp ^ *yp;
}
int main()
{
int x = 10;
swap(&x, &x);
printf("After swap(&x, &x): x = %d", x);
return 0;
}
Wyjście :
Po zamianie (& x, & x): x = 0
Zamiana zmiennej może być potrzebna w wielu standardowych algorytmach. Na przykład zobacz tę implementację QuickSort, w której możemy zamienić zmienną ze sobą. Powyższego problemu można uniknąć, stawiając warunek przed zamianą.
#include <stdio.h>
void swap(int *xp, int *yp)
{
if (xp == yp) // Check if the two addresses are same
return;
*xp = *xp + *yp;
*yp = *xp - *yp;
*xp = *xp - *yp;
}
int main()
{
int x = 10;
swap(&x, &x);
printf("After swap(&x, &x): x = %d", x);
return 0;
}
Wyjście :
Po zamianie (& x, & x): x = 10