Hãy xem một ví dụ c đơn giản để hoán đổi hai số mà không sử dụng biến thứ ba.
chương trình 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();
}
Đầu ra:
Trước khi hoán đổi a = 10 b = 20 Sau khi hoán đổi a = 20 b = 10
Chương trình 2: Sử dụng * và /
Hãy xem một ví dụ khác để hoán đổi hai số bằng cách sử dụng * và /.
#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();
}
Đầu ra:
Trước khi hoán đổi a = 10 b = 20 Sau khi hoán đổi a = 20 b = 10
Chương trình 3: Sử dụng toán tử XOR bitwise:
Toán tử XOR bitwise có thể được sử dụng để hoán đổi hai biến. XOR của hai số x và y trả về một số có tất cả các bit là 1 bất cứ nơi nào các bit của x và y khác nhau. Ví dụ: XOR của 10 (Trong nhị phân 1010) và 5 (Trong nhị phân 0101) là 1111 và XOR của 7 (0111) và 5 (0101) là (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;
Đầu ra:
Sau khi hoán đổi: x = 5, y = 10
Chương trình 4:
Chưa có ai đề xuất sử dụng std :: swap.
std::swap(a, b);
Tôi không sử dụng bất kỳ biến tạm thời nào và tùy thuộc vào kiểu a và b, việc triển khai có thể có một chuyên môn hóa không. Việc triển khai phải được viết ra để biết liệu một 'thủ thuật' có phù hợp hay không.
Sự cố với các phương pháp trên:
1) Cách tiếp cận dựa trên phép nhân và phép chia sẽ không hoạt động nếu một trong các số là 0 vì tích trở thành 0 bất kể số còn lại.
2) Cả hai giải pháp Số học có thể gây ra tràn số học. Nếu x và y quá lớn, phép cộng và phép nhân có thể nằm ngoài phạm vi số nguyên.
3) Khi chúng ta sử dụng con trỏ đến một biến và thực hiện hoán đổi hàm, tất cả các phương pháp trên đều thất bại khi cả hai con trỏ đều trỏ đến cùng một biến. Hãy xem điều gì sẽ xảy ra trong trường hợp này nếu cả hai đều trỏ đến cùng một biến.
// Phương thức dựa trên Bitwise XOR
x = x ^ x; // x becomes 0
x = x ^ x; // x remains 0
x = x ^ x; // x remains 0
// Phương pháp dựa trên số học
x = x + x; // x becomes 2x
x = x – x; // x becomes 0
x = x – x; // x remains 0
Hãy cùng chúng tôi xem chương trình sau đây.
#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;
}
Đầu ra :
Sau khi hoán đổi (& x, & x): x = 0
Việc hoán đổi một biến với chính nó có thể cần thiết trong nhiều thuật toán tiêu chuẩn. Ví dụ, hãy xem triển khai QuickSort này, nơi chúng ta có thể hoán đổi một biến với chính nó. Vấn đề trên có thể tránh được bằng cách đặt một điều kiện trước khi hoán đổi.
#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;
}
Đầu ra :
Sau khi hoán đổi (& x, & x): x = 10