×

Cài đặt thuật toán Karatsuba trong lập trình

Hướng dẫn cài đặt thuật toán Karatsuba trong lập trình

Thuật toán Karatsuba là một phương pháp hiệu quả để nhân hai số lớn. Nó được đánh giá cao vì khả năng giảm độ phức tạp từ O(n^2) trong kỹ thuật nhân thông thường xuống O(n^log3) (với log3 là log cơ số 2 của 3). Trong bài viết này, chúng ta sẽ đi sâu vào cách cài đặt thuật toán Karatsuba trong lập trình.

Nguyên lý hoạt động của thuật toán Karatsuba

Thuật toán Karatsuba sử dụng kỹ thuật "chia để trị" để phân chia hai số cần nhân thành các phần nhỏ hơn. Cụ thể, ta có hai số x và y với n chữ số, được phân chia thành hai nửa x1, x0 và y1, y0 như sau:

  • x = x1 * 10^(n/2) + x0
  • y = y1 * 10^(n/2) + y0

Sau đó, chúng ta sẽ tính ba tích con:

  1. z2 = x1 * y1
  2. z0 = x0 * y0
  3. z1 = (x1 + x0) * (y1 + y0) - z2 - z0

Tích của x và y sẽ được tính bằng:

  • result = z2 * 10^n + (z1 * 10^(n/2)) + z0

Cài đặt thuật toán Karatsuba trong Python

Dưới đây là một ví dụ chi tiết về cách cài đặt thuật toán Karatsuba trong Python:

def karatsuba(x, y):
    # Chuyển đổi x và y thành chuỗi để dễ chia nhỏ
    x, y = str(x), str(y)
    
    # Độ dài của x và y
    n = max(len(x), len(y))
    
    # Nếu chiều dài ngắn, hãy thực hiện phép nhân trực tiếp
    if n == 1:
        return int(x) * int(y)
    
    # Làm cho độ dài của x và y bằng nhau bằng cách thêm 0 vào bên trái
    n = (n // 2) + (n % 2)
    
    # Chia chuỗi thành hai phần
    x1, x0 = int(x[:-n] or 0), int(x[-n:] or 0)
    y1, y0 = int(y[:-n] or 0), int(y[-n:] or 0)
    
    # Thực hiện ba tích con
    z2 = karatsuba(x1, y1)
    z0 = karatsuba(x0, y0)
    z1 = karatsuba(x1 + x0, y1 + y0) - z2 - z0
    
    # Kết hợp các tích lại để tính kết quả
    return (z2 * 10**(2*n)) + (z1 * 10**n) + z0

# Ví dụ sử dụng
num1 = 12345678
num2 = 87654321
result = karatsuba(num1, num2)
print(f"Kết quả của phép nhân Karatsuba giữa {num1} và {num2} là: {result}")

Trong ví dụ trên, thuật toán chia số thành các phần x1, x0 và y1, y0, sau đó thực hiện phép nhân theo nguyên lý Karatsuba. Kết quả cuối cùng được kết hợp từ ba tích con để cho ra kết quả cuối cùng.

Để áp dụng thuật toán Karatsuba vào các ngôn ngữ lập trình khác như C++, Java, hay JavaScript, bạn cần hiểu cách thức này có thể dịch sang các cú pháp cụ thể của ngôn ngữ đó. Dưới đây là một phác thảo ngắn về cách thực hiện trong C++:

#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>

using namespace std;

long long karatsuba(long long x, long long y) {
    // Chuyển đổi x và y thành chuỗi để dễ chia nhỏ
    string sx = to_string(x);
    string sy = to_string(y);
    
    // Độ dài của x và y
    int n = max(sx.length(), sy.length());
    
    // Nếu chiều dài ngắn, hãy thực hiện phép nhân trực tiếp
    if (n == 1) {
        return x * y;
    }
    
    // Làm cho độ dài của x và y bằng nhau bằng cách thêm 0 vào bên trái
    n = (n / 2) + (n % 2);
    
    // Chia số thành hai phần
    long long x1 = x / pow(10, n);
    long long x0 = x % long(pow(10, n));
    long long y1 = y / pow(10, n);
    long long y0 = y % long(pow(10, n));
    
    // Thực hiện ba tích con
    long long z2 = karatsuba(x1, y1);
    long long z0 = karatsuba(x0, y0);
    long long z1 = karatsuba(x1 + x0, y1 + y0) - z2 - z0;
    
    // Kết hợp các tích lại để tính kết quả
    return (z2 * pow(10, 2 * n)) + (z1 * pow(10, n)) + z0;
}

// Ví dụ sử dụng
int main() {
    long long num1 = 12345678;
    long long num2 = 87654321;
    long long result = karatsuba(num1, num2);
    cout << "Kết quả của phép nhân Karatsuba giữa " << num1 << " và " << num2 << " là: " << result << endl;
    return 0;
}

Kết luận

Cài đặt thuật toán Karatsuba không chỉ giúp bạn nâng cao hiệu suất tính toán của các phép nhân lớn mà còn giúp bạn hiểu rõ hơn về các kỹ thuật "chia để trị". Hy vọng rằng bài viết này sẽ giúp bạn dễ dàng áp dụng thuật toán Karatsuba trong các ngôn ngữ lập trình khác nhau.

Comments