手写前缀树以及使用前缀树实现敏感词过滤

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

// 前缀树
public class Trie {
    // 子节点
    private Trie[] children;
    // 终点标识
    private boolean isEnd;

    public Trie(){
        children = new Trie[26];
        isEnd = false;
    }

    // 插入
    public void insert(String word) {
        Trie trie = this;

        for (int i = 0; i < word.length(); i++) {
            char c = word.charAt(i);

            if (trie.children[c-'a'] == null){
                trie.children[c-'a'] = new Trie();
            }
            trie = trie.children[c-'a'];
        }
        trie.isEnd = true;
    }

    // 搜索
    public boolean search(String word) {
        Trie trie = this;
        for (int i = 0; i < word.length(); i++) {
            char c = word.charAt(i);

            if (trie.children[c-'a'] == null){
                return false;
            }
            trie = trie.children[c-'a'];
        }
        return trie.isEnd;
    }

    // 获取坐标
    public int mateIndex(String word) {
        Trie trie = this;
        for (int i = 0; i < word.length(); i++) {
            char c = word.charAt(i);

            if (trie.children[c-'a'] == null){
                return trie.isEnd ? i : -1;
            }
            trie = trie.children[c-'a'];
        }
        return trie.isEnd ? word.length() : -1;
    }

    // 是否在树中存在前缀
    public boolean startsWith(String prefix) {
        Trie trie = this;
        for (int i = 0; i < prefix.length(); i++) {
            char c = prefix.charAt(i);

            if (trie.children[c-'a'] == null){
                return false;
            }
            trie = trie.children[c-'a'];
        }
        return true;
    }

    /**
     * TODO
     * 敏感词过滤,首先,输入m,表示有m个敏感词。然后,在输入n,表示有n个字符串,每次字符串输入后,输出过滤后的结果。在字符串包含敏感词则用*号表示。
     *
     * Input
     * 3
     * aaa
     * bbb
     * ccc
     * 2
     * aaabbcc
     * aaaabbccc
     *
     * Ouput
     * ***bbcc
     * ****bb***
     */
    public static void main(String[] args) {
        Trie trie = new Trie();

        Scanner sc = new Scanner(System.in);

        int m = sc.nextInt();

        for (int i = 0; i < m; i++) {
            String param = sc.next();
            trie.insert(param);
        }

        int n = sc.nextInt();
        List<String> ans = new ArrayList<>(n);
        for (int i = 0; i < n; i++) {
            String param = sc.next();
            boolean[] flag = new boolean[param.length()];
            for (int j = 0; j < param.length(); j++) {
                String substring = param.substring(j);

                int mateIndex = trie.mateIndex(substring);
                if (mateIndex == -1){
                    continue;
                }
                Arrays.fill(flag,j,j+mateIndex,true);

            }
            StringBuilder st = new StringBuilder();
            for (int j = 0; j < flag.length; j++) {
                if (flag[j]){
                    st.append("*");
                }else {
                    st.append(param.charAt(j));
                }
            }
            ans.add(st.toString());
        }

        for (int i = 0; i < ans.size(); i++) {
            System.out.println(ans.get(i));
        }
    }
}
posted @ 2025-04-20 16:39  ayu0v0  阅读(19)  评论(0)    收藏  举报