Khoá học C++ nâng cao
Bài học: Xử Lý Chuỗi Ký Tự, String Hashing & Số Nguyên Lớn
🏆 +100 XP tiềm năng Thoát

Xử Lý Chuỗi Ký Tự, String Hashing & Số Nguyên Lớn

2 khối nội dung 45 phút học tập MỞ BẢNG TRẮNG

Xử Lý Chuỗi Ký Tự, String Hashing & Số Nguyên Lớn

Nội dung bài học

1. Khái niệm & cấu trúc 3 phần của Chuyên đề 15

Chuyên đề 15 là bài học tổng hợp cuối cùng của khóa học Level 2, tích hợp 3 mảng kiến thức lớn:

  1. 15.1. Xử lý xâu cơ bản & Palindrome: Các thao tác chuẩn trên string, đếm tần suất ký tự, kỹ thuật mở rộng tâm (Expand Around Center) tìm xâu con đối xứng dài nhất trong $\mathcal{O}(N^2)$.
  2. 15.2. Kỹ thuật Băm chuỗi đa thức (Rolling Hash / Polynomial Hashing): Biến đổi một xâu ký tự thành một số nguyên duy nhất theo modulo, cho phép so sánh hai xâu con bất kỳ $S[L \dots R]$ trong thời gian $\mathcal{O}(1)$ (thay vì $\mathcal{O}(N)$).
  3. 15.3. Xử lý số nguyên lớn (Big Integer): Tự xây dựng cấu trúc số nguyên lớn để thực hiện các phép cộng, trừ, nhân hai số có hàng nghìn chữ số.

Cây tiền tố Trie

2. Kỹ thuật Băm chuỗi đa thức

2.1. Công thức hàm băm tiền tố

Cho xâu $S$ độ dài $N$, cơ số $Base = 311$ (hoặc $31$) và modulo $MOD = 10^9 + 7$:

  • Mảng băm tiền tố $hash[i] = (S[0] \cdot Base^i + S[1] \cdot Base^{i-1} + \dots + S[i]) \bmod MOD$.
  • Công thức tính mã băm của đoạn con $S[L \dots R]$ (1-based) trong $\mathcal{O}(1)$: $$\text{get\_hash}(L, R) = (hash[R] - hash[L - 1] \times Base^{R - L + 1} \bmod MOD + MOD) \bmod MOD$$

2.2. Kỹ thuật Băm kép (Double Hash) chống đụng độ $100\%$

Để tránh việc hai xâu khác nhau có cùng mã băm (Hash Collision) do nguyên lý Dirichlet khi số lượng truy vấn lớn ($Q = 10^5$), ta sử dụng đồng thời hai cặp $(Base_1, MOD_1)$ và $(Base_2, MOD_2)$ khác nhau (ví dụ: $MOD_1 = 10^9+7, MOD_2 = 10^9+9$). Mã băm lúc này là một cặp số pair<long long, long long>. Khả năng đụng độ giảm xuống $\frac{1}{MOD_1 \times MOD_2} \approx 10^{-18}$ (gần như bằng 0 tuyệt đối).

const long long BASE = 311;
const long long MOD = 1000000007;

long long h[1000005];
long long pw[1000005];

void init_hash(const string &s) {
    int n = s.size();
    pw[0] = 1;
    for (int i = 1; i <= n; ++i) pw[i] = (pw[i - 1] * BASE) % MOD;

    h[0] = 0;
    for (int i = 0; i < n; ++i) {
        h[i + 1] = (h[i] * BASE + s[i]) % MOD;
    }
}

long long get_hash(int l, int r) { // 1-based indexing
    long long res = (h[r] - h[l - 1] * pw[r - l + 1]) % MOD;
    return (res + MOD) % MOD;
}

3. Cấu trúc số nguyên lớn (Big Integer Addition, Subtraction, Multiplication)

3.1. Phép cộng hai số nguyên lớn

string add_bigint(string a, string b) {
    while (a.size() < b.size()) a = "0" + a;
    while (b.size() < a.size()) b = "0" + b;

    int carry = 0;
    string res = "";
    for (int i = (int)a.size() - 1; i >= 0; --i) {
        int sum = (a[i] - '0') + (b[i] - '0') + carry;
        carry = sum / 10;
        res += to_string(sum % 10);
    }
    if (carry) res += to_string(carry);
    reverse(res.begin(), res.end());
    return res;
}

3.2. Phép nhân hai số nguyên lớn

string multiply_bigint(string a, string b) {
    int n = a.size(), m = b.size();
    vector<int> res(n + m, 0);

    for (int i = n - 1; i >= 0; --i) {
        for (int j = m - 1; j >= 0; --j) {
            int mul = (a[i] - '0') * (b[j] - '0');
            int p1 = i + j, p2 = i + j + 1;
            int sum = mul + res[p2];

            res[p2] = sum % 10;
            res[p1] += sum / 10;
        }
    }

    string s = "";
    for (int val : res) {
        if (!(s.empty() && val == 0)) s += to_string(val);
    }
    return s.empty() ? "0" : s;
}

4. Ranh giới áp dụng

Tình Huống Bài Toán Kỹ Thuật Tối Ưu Độ Phức Tạp
So sánh nhiều xâu con, tìm xâu con chung, đếm xâu đối xứng String Hashing (Rolling Hash) Tiền xử lý $\mathcal{O}(N)$, truy vấn $\mathcal{O}(1)$
Phép tính số học với số có độ dài đến $10^4$ chữ số Big Integer Cộng $\mathcal{O}(N)$, Nhân $\mathcal{O}(NM)$
Khớp mẫu xâu cơ bản KMP hoặc String Hashing $\mathcal{O}(N + M)$

1
A
B
C
D
2
A
B
C
D

Bài tập lập trình vận dụng

24 Bài tập thực hành

Nhấn vào nút "Làm bài" bên dưới để mở giao diện làm bài trực tuyến (Online Judge) và thực hiện viết mã nguồn cho bài tập này.

Truy vấn so khớp xâu con hashing
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Nhân hai số nguyên lớn
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Truy vấn so khớp hai xâu con bằng hashing
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Tìm xâu mẫu p trong xâu văn bản t (string match)
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Xâu con đối xứng dài nhất (longest palindromic substring)
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Đếm số xâu con khác nhau của một xâu
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Xâu con lặp lại dài nhất xuất hiện ít nhất k lần
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Tính giai thừa $n!$ cho $n = 1000$ bằng BigInt
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Thuật toán Manacher tìm mọi palindrome tuyến tính $\mathcal{o}(n)$
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Tìm chu kỳ ngắn nhất của xâu ký tự (string period)
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Thuật toán Manacher tìm mọi palindrome tuyến tính $\mathcal{o}(n)$
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Thuật toán KMP (knuth-morris-pratt) & mảng tiền tố $\pi$
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Căn bậc hai của số nguyên lớn
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Chia hai số nguyên lớn cho nhau (BigInt / BigInt)
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Xâu con chung dài nhất của k xâu ký tự
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Mảng hậu tố (suffix array) bằng string hashing $\mathcal{o}(n \log^2 n)$
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Double hashing chong va cham
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Thuat toan Manacher palindrome
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Z algorithm tim mau
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
KMP Knuth morris pratt
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Cay Trie xau co ban
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Chia so nguyen lon BigInt
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Can bac hai so nguyen lon
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài
Aho-Corasick da mau tim kiem
Độ khó: mediumĐiểm tối đa: 100.0 điểm
Làm bài