Bài tập

Hàm swap trong lập trình C/C++ - Tạo sự hoán vị giữa hai biến

Huy Erick

Bạn đã bao giờ gặp phải một bài toán trong lập trình mà bạn cần hoán đổi giá trị của hai biến với nhau? Ví dụ như trong bài toán sắp xếp? Trong bài viết...

Bạn đã bao giờ gặp phải một bài toán trong lập trình mà bạn cần hoán đổi giá trị của hai biến với nhau? Ví dụ như trong bài toán sắp xếp? Trong bài viết này, chúng ta sẽ cùng tìm hiểu về tư tưởng bài toán hoán vị và cách viết hàm swap trong lập trình C/C++.

Tư tưởng bài toán hoán vị

Hãy tưởng tượng bạn có hai cốc nước, gọi là cốc A chứa nước lọc và cốc B chứa nước cam. Làm sao để hoán đổi nước cam từ cốc A sang cốc B và ngược lại?

Để thực hiện việc này, chúng ta cần một cốc phụ, gọi là cốc C. Quá trình hoán đổi được thực hiện như sau:

  • Bước 1: Đổ nước lọc từ cốc A vào cốc C.
  • Bước 2: Đổ nước cam từ cốc B vào cốc A.
  • Bước 3: Đổ nước lọc từ cốc C vào cốc B.

Kết quả cuối cùng là cốc A chứa nước cam và cốc B chứa nước lọc. Trên cùng cơ sở tư tưởng, chúng ta cũng thực hiện việc hoán đổi giá trị của hai biến A và B trong lập trình. Đầu tiên, chúng ta khai báo một biến tạm gọi là temp, sau đó gán temp = A, A = B, B = temp. Như vậy, giá trị của hai biến A và B đã được hoán đổi.

Hàm swap có sẵn trong thư viện C++

Trong thư viện iostream của C++, đã có sẵn hàm swap với cấu trúc:

void swap(object A, object B)

Trong đó, A và B có thể là bất kỳ kiểu dữ liệu nào từ int, float, struct hoặc thậm chí là một đối tượng class.

Dưới đây là một đoạn code minh hoạ việc hoán đổi giá trị của hai biến kiểu int:

#include 
using namespace std;

int main()
{
    int a, b;
    cout  "Nhap 2 so a, b: ";
    cin >> a >> b;

    cout  "Ban da nhap: a = "  a  ", b = "  b  endl;

    swap(a, b);

    cout  "Sau khi swap: a = "  a  ", b = "  b  endl;

    return 0;
}

Kết quả khi chạy chương trình sẽ như sau:

Nhap 2 so a, b: 3 5
Ban da nhap: a = 3, b = 5
Sau khi swap: a = 5, b = 3

Viết hàm hoán vị không sử dụng hàm swap con

Một cách hoán vị giữa hai biến mà không sử dụng hàm swap con là viết trực tiếp trong hàm main. Tuy nhiên, đây chỉ là một ví dụ minh họa và không thực tế, vì mỗi lần hoán đổi hai phần tử, chúng ta phải viết lại lệnh hoán đổi, điều này không tối ưu.

Dưới đây là một đoạn code mẫu:

#include 
using namespace std;

int main()
{
    int a, b;
    cout  "Nhap 2 so a, b: ";
    cin >> a >> b;

    cout  "Ban da nhap: a = "  a  ", b = "  b  endl;

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

    cout  "Sau khi swap: a = "  a  ", b = "  b  endl;

    return 0;
}

Kết quả khi chạy chương trình sẽ như ví dụ trên.

Viết hàm hoán vị với C

Dưới đây là một đoạn chương trình con trong C. Hãy dự đoán kết quả trước khi chạy chương trình nhé!

#include 

void swap(int a, int b)
{
    int temp = a;
    a = b;
    b = temp;
}

int main()
{
    int a = 3, b = 5;
    printf("Truoc hoan vi: a = %d, b = %d\n", a, b);

    swap(a, b);

    printf("Sau hoan vi: a = %d, b = %d\n", a, b);

    return 0;
}

Và đây là kết quả khi chạy chương trình:

Truoc hoan vi: a = 3, b = 5
Sau hoan vi: a = 3, b = 5

Ồ, tại sao chương trình không thể hoán đổi giá trị của hai biến như mong đợi? Vì khi ta viết hàm Swap như vậy, ta chỉ đang truyền tham trị (giá trị của a và b) vào hàm swap mà không truyền địa chỉ ô nhớ của hai biến a và b. Do đó, hàm swap sẽ tạo ra hai bản sao tại địa chỉ ô nhớ khác nhau và thao tác trên hai ô nhớ mới đó. Hai biến a và b sau khi thoát khỏi hàm vẫn giữ nguyên giá trị ban đầu của chúng.

Để khắc phục tình trạng này, chúng ta sử dụng tham trỏ trong C. Bằng cách truyền địa chỉ của biến a và b vào hàm swap thông qua tham trỏ, chúng ta có thể hoán đổi giá trị của hai biến.

Dưới đây là phiên bản chương trình đã được sửa:

#include 

void swap(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main()
{
    int a = 3, b = 5;
    printf("Truoc hoan vi: a = %d, b = %d\n", a, b);

    swap(&a, &b);

    printf("Sau hoan vi: a = %d, b = %d\n", a, b);

    return 0;
}

Và đây là kết quả khi chạy chương trình:

Truoc hoan vi: a = 3, b = 5
Sau hoan vi: a = 5, b = 3

Chương trình đã chạy đúng như mong đợi.

Viết hàm hoán vị với C++

Đối với C++, chúng ta cũng có thể viết hàm swap tương tự. Tuy nhiên, trong C++ có khái niệm tham chiếu (hay gọi là tham biến), làm cho đoạn code trông đơn giản và dễ hiểu hơn so với việc sử dụng tham trỏ trong C.

Dưới đây là một đoạn code mẫu:

#include 
using namespace std;

void swap(int &a, int &b)
{
    int temp = a;
    a = b;
    b = temp;
}

int main()
{
    int a, b;
    cout  "Nhap 2 so a, b: ";
    cin >> a >> b;

    cout  "Ban da nhap: a = "  a  ", b = "  b  endl;

    swap(a, b);

    cout  "Sau khi swap: a = "  a  ", b = "  b  endl;

    return 0;
}

Kết quả khi chạy chương trình sẽ như sau:

Nhap 2 so a, b: 2 5
Ban da nhap: a = 2, b = 5
Sau khi swap: a = 5, b = 2

Cuối cùng, xin cảm ơn bạn đã đọc bài viết và chúc bạn học tốt! Sớm trở thành một Pro Dev.

[Xem tất cả bài viết chủ đề C/C++ tại đây]

1