字串板子

Aderose_yr發表於2024-10-18

trie(這個算資料結構嗎

// 原題為16進位制trie,將就看看吧)
string a[N];
int to[N * 22][18], x[N * 22];
int cnt;
void add(int id) {
    string s = a[id];
    int cur = 0;
    for(int i = 0; i <= 19; i++) {
        int t;
        if(s[i] >= '0' && s[i] <= '9') {
            t = s[i] - '0';
        } else {
            t = 10 + s[i] - 'A';
        }
        if(to[cur][t] == 0) to[cur][t] = ++cnt;
        cur = to[cur][t];
    }
    x[cur] = id;
}
int query(string &s) {
    int cur = 0;
    for(int i = 19; i >= 0; i--) {
        int t;
        if(s[i] >= '0' && s[i] <= '9') {
            t = s[i] - '0';
        } else {
            t = 10 + s[i] - 'A';
        }
        int val = -1, ans = 0;
        for(int r = 0; r < 16; r++) {
            if(to[cur][r] && (t + r) % 16 > val) {
                val = (t + r) % 16;
                ans = r;
            }
        }
        cur = to[cur][ans];
    }
    return x[cur];
}

KMP

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6 + 10;
int n, m;
char s1[N], s2[N];
int f[N], l[N];
void getfail() {
    for(int i = 2, j = 0; i <= m; i++) {
        while (j && s2[i] != s2[j + 1]) j = f[j];
        if (s2[j + 1] == s2[i]) j ++;
        f[i] = j;
    }
}
int main() {
	scanf("%s%s", s1 + 1, s2 + 1);
    n = strlen(s1 + 1), m = strlen(s2 + 1);
    getfail();
    for(int i = 1, j = 0; i <= n; i++) {
        while(j && (j == n || s1[i] != s2[j + 1])) j = f[j];
        if(s1[i] == s2[j + 1]) j++;
        l[i] = j;
        if(l[i] == m) printf("%d\n", i - m + 1);
    }
    for(int i = 1; i <= m; i++) printf("%d ", f[i]);
 
    system("pause");
    return 0;
}

相關文章