Wiki Thuật toán Thuật toán xâu

Thuật toán xâu

huunguyen huunguyen Updated Tháng sáu 2, 2026

String Hashing

So sánh chuỗi con trong O(1) sau O(N) tiền xử lý.

const long long MOD=1e9+7, BASE=31;
string s; int n=s.size();
vector<long long> h(n+1,0), pw(n+1,1);
for (int i=0; i<n; i++) {
    h[i+1]=(h[i]*BASE+(s[i]-'a'+1))%MOD;
    pw[i+1]=pw[i]*BASE%MOD;
}
auto get_hash=[&](int l,int r){
    return (h[r+1]-h[l]*pw[r-l+1]%MOD+MOD*2)%MOD;
};

KMP — O(|t|+|p|)

vector<int> kmp_search(string t, string p) {
    string s=p+"#"+t; int n=s.size();
    vector<int> fail(n,0);
    for (int i=1; i<n; i++) {
        int j=fail[i-1];
        while (j>0 && s[i]!=s[j]) j=fail[j-1];
        if (s[i]==s[j]) j++;
        fail[i]=j;
    }
    vector<int> res; int m=p.size();
    for (int i=m+1; i<n; i++) if (fail[i]==(int)m) res.push_back(i-2*m);
    return res;
}

Z-function — O(N)

z[i] = độ dài tiền tố dài nhất của s khớp với chuỗi tại s[i].

vector<int> z_function(string s) {
    int n=s.size(); vector<int> z(n,0); z[0]=n;
    int l=0,r=0;
    for (int i=1; i<n; i++) {
        if (i<r) z[i]=min(r-i,z[i-l]);
        while (i+z[i]<n && s[z[i]]==s[i+z[i]]) z[i]++;
        if (i+z[i]>r) { l=i; r=i+z[i]; }
    }
    return z;
}
// Tìm pattern p trong text t: s = p+"#"+t, z[i]>=|p| là vị trí khớp

Trie

struct Trie {
    int ch[26]; bool end;
    Trie(): end(false) { fill(ch,ch+26,-1); }
};
vector<Trie> trie(1);

void insert(string& s) {
    int cur=0;
    for (char c:s) {
        int x=c-'a';
        if (trie[cur].ch[x]==-1) { trie[cur].ch[x]=trie.size(); trie.push_back(Trie()); }
        cur=trie[cur].ch[x];
    }
    trie[cur].end=true;
}

Bảng so sánh

Thuật toán Thời gian Ứng dụng
Hashing O(N) build, O(1) query So sánh chuỗi con
KMP O(N+M) Tìm pattern trong text
Z-function O(N) Tìm pattern, period
Trie O(s) Từ điển, XOR max
Aho-Corasick O(pi+text) Tìm nhiều pattern đồng thời
Manacher O(N) Palindrome dài nhất
Suffix Array O(NlogN) Chuỗi con, LCS, so sánh từ điển
Suffix Automaton O(N) Đếm xâu con phân biệt, LCS, đếm số lần xuất hiện
Palindrome Tree O(N) Tất cả palindrome con phân biệt
gnatmake 12.2.0 a68g 3.1.2 nasm 2.16.1 as_x64 2.46 awk 1.3.4 gcc 16.1.0 csc 6.12.0.200 g++ 16.1.0 g++-themis 16.1.0 g++17 16.1.0 g++20 16.1.0 g++23 16.1.0 clang++ 22.1.6 dmd 2.112.0 dart 3.12.1 gforth 0.7.3 gfortran 12.2.0 go 1.26.3 groovyc 5.0.6 javac 25.0.3 node 26.2.0 kotlinc 2.3.21 sbcl 2.2.9 lua 5.4.8 nim 2.2.10 fpc 3.2.2 fpc-themis 3.2.2 perl 5.36.0 php 8.5.6 pike 8.0 pypy3 7.3.23 python3 3.14.5 racket 8.7 ruby 4.0.5 rustc 1.96.0 csc 5.3.0 ctoj-scratch 0.0.1 sed 4.9 tclsh 8.6 bun 1.3.14 deno 2.8.1 v 0.5.1 zig 0.16.0