第四章高级数据结构(七)

AC自动机

例题:搜索关键词
在这里插入图片描述
输入样例:
1
5
she
he
say
shr
her
yasherhs
输出样例:
3
——————————————————————————————————————————————————————
【RE】了

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    static int N = 10010;
    static int S = 55;
    static int M = 1000010;
    static int n;
    static int[][] tr = new int[N * S][26];
    static int[] cnt = new int[N * S];
    static int idx;
    static char[] str = new char[M];
    static int[] q = new int[N * S];
    static int[] ne = new int[N * S];

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        while (T-- > 0) {
            for (int[] x : tr) Arrays.fill(x, 0);
            Arrays.fill(cnt, 0);
            Arrays.fill(ne, 0);
            idx = 0;
            n = sc.nextInt();
            for (int i = 0; i < n; i++) {
                str = sc.next().toCharArray();
                insert();
            }
            build();
            str = sc.next().toCharArray();
            int res = 0;
            for (int i = 0, j = 0; str[i] != 0 ; i++) {//存疑
                int t = str[i] - 'a';
                while (j > 0 && tr[j][t] == 0) j = ne[j];
                if (tr[j][t] != 0) j = tr[j][t];
                int p = j;
                while (p != 0) {
                    res += cnt[p];
                    cnt[p] = 0;
                    p = ne[p];
                }
            }
            System.out.println(res);
        }
    }

    private static void build() {
        int hh = 0, tt = 1;
        for (int i = 0; i < 26; i++) {
            if (tr[0][i] != 0) {
                q[++tt] = tr[0][i];
            }
        }
        while (hh <= tt) {
            int t = q[hh++];
            for (int i = 0; i < 26; i++) {
                int c = tr[t][i];
                if (c == 0) continue;
                int j = ne[t];
                while (j != 0 && tr[i][j] == 0) {
                    j = ne[j];
                }
                if (tr[j][i] != 0) j = tr[j][i];
                ne[c] = j;
                q[++tt] = c;
            }
        }
    }

    private static void insert() {
        int p = 0;
        for (int i = 0; str[i] != 0; i++) {//存疑 '\0'
            int t = str[i] - 'a';
            if (tr[p][t] == 0) {
                tr[p][t] = ++idx;
                p = tr[p][t];
            }
        }
        cnt[p]++;
    }
}

1053.修复DNA
在这里插入图片描述
在这里插入图片描述
输入样例:
2
AAA
AAG
AAAG
2
A
TG
TGAATG
4
A
G
C
T
AGT
0
输出样例:
Case 1: 1
Case: 2: 4
Case 3: -1
————————————————————————————————————————————————————
(略)

例题:单词
【题目描述】
原题来自:TJOI 2013
某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。
【输入】
第一个一个整数 N,表示有多少个单词,接下来 N 行每行一个单词。
【输出】
输出 N 个整数,第 i 行的数字表示第 i 个单词在文章中出现了多少次。
【输入样例】
3
a
aa
aaa
【输出样例】
6
3
1
【提示】
数据范围:
对于全部数据,1≤N≤200,所有单词长度的和不超过 106​​ ,保证每个单词由小写字母组成。
——————————————————————————————————————————————————
(略)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值