Javaの文字列アルゴリズム

1.トライツリー

import java.util.ArrayList;
import java.util.Queue;

//单词查找树,就是trie树,如果加上失配指针就是AC自动机
public class TrieST<Value> {
    
    
    private static int R = 256;

    //基于链表
    private static class Node {
    
    
        private Object val;
        private Node[] next = new Node[R];//这里存在
    }

    private Node root;

    /*
     * 插入值的接口
     * 输入,键值
     * 输出,单词的编码
     * 没有键,输出Null;
     * */
    public Value get(String key) {
    
    
        Node x = get(root, key, 0);
        if (x == null) return null;
        return (Value) x.val;
    }

    /*
     * 查询一个单词在词典中出现的次数
     * 1.输入:单词查找树,带查找的键,指向键的指针
     * 2.输出:查找树和键匹配的节点,不匹配输出null
     * */
    private Node get(Node x, String key, int d) {
    
    
        if (x == null) return null;
        if (d == key.length()) return x;
        char c = key.charAt(d);        //找到第d个字符所对应的单词查找树
        return get(x.next[c], key, d + 1);
    }
    /*
     *
     * 插入操作,为每个词编一个码
     * */

    public void put(String key, Value value) {
    
    
        root = put(root, key, value, 0);
    }

    private Node put(Node x, String key, Value val, int d) {
    
    
        if (x == null) x = new Node();
        if (d == key.length()) {
    
    
            x.val = val;
            return x;
        }
        char c = key.charAt(d);        //找到第d个字符对应的单词查找树
        x.next[c] = put(x.next[c], key, val, d + 1);
        return x;
    }

    public String longestPrefixOf(String s) {
    
    
        int length = search(root, s, 0, 0);
        return s.substring(0, length);
    }

    private int search(Node x, String s, int d, int length) {
    
    
        if (x == null) return length;
        if (x.val != null) length = d;
        if (d == s.length()) return length;
        char c = s.charAt(d);
        return search(x.next[c], s, d + 1, length);
    }

    public void delete(String key) {
    
    
        root = delete(root, key, 0);
    }

    public Node delete(Node x, String key, int d) {
    
    
        if (x == null) return null;
        if (d == key.length()) {
    
    
            x.val = null;
        } else {
    
    
            char c = key.charAt(d);
            x.next[c] = delete(x.next[c], key, d + 1);
        }
        if (x.val != null) return x;
        for (char c = 0; c < R; c++) {
    
    
            if (x.next[c] != null) return x;
        }
        return null;
    }

    /*
     * 获取单词查找树单词的数目
     * */
    public int size() {
    
    
        return size(root);
    }

    /*
     * 深度优先搜索
     * */
    private int size(Node x) {
    
    
        if (x == null) return 0;

        int cnt = 0;
        if (x.val != null) cnt++;
        for (char c = 0; c < R; c++) {
    
    
            cnt += size(x.next[c]);
        }
        return cnt;
    }

    /*
     * 查找所有的键
     * */
    public Iterable<String> keys(String s) {
    
    
        return keysWithPrefix("");
    }

    /*
     * 查找以s为前缀的键
     * */
    public Iterable<String> keysWithPrefix(String s) {
    
    
        ArrayList<String> arrayList = new ArrayList<>();
        collect(get(root, s, 0), s, arrayList);
        return arrayList;
    }

    /*
     *深度优先搜索得到
     * */
    private void collect(Node x, String pre, ArrayList<String> q) {
    
    
        if (x == null) return;
        if (x.val != null) q.add(pre);
        for (char c = 0; c < R; c++)
            collect(x.next[c], pre + c, q);
    }

    public static void main(String[] args) {
    
    
        TrieST<Integer> st = new TrieST<>();
        String s = "fdadfa";
        String pre = "fda";
        st.put(pre, 1);
        System.out.println(st.get(pre));
        System.out.println(st.get(s));
        System.out.println(st.longestPrefixOf(s));
        st.delete(pre);
        System.out.println(st.get(pre));
    }
}


2.KMP

public class KMP {
    
    
    private String pat;
    private int[][] dfa;

    public KMP(String pat) {
    
    
        this.pat = pat;
        int M = pat.length();
        int R = 256;
        dfa = new int[R][M];
        dfa[pat.charAt(0)][0] = 1;
        for (int X = 0, j = 1; j < M; j++) {
    
    
            //计算dfa[][j];
            for (int c = 0; c < R; c++)
                dfa[c][j] = dfa[c][X];     //复制匹配失败情况下的值
            dfa[pat.charAt(j)][j] = j + 1;//设置匹配成功情况下的值
            X = dfa[pat.charAt(j)][X];   //更新重启状态
        }
    }

    public int search(String txt) {
    
    
        //在txt上模拟DFA的运行
        int i, j, N = txt.length(), M = pat.length();
        for (i = 0, j = 0; i < N && j < M; i++)
            j = dfa[txt.charAt(i)][j];
        if (j == M) return i - M;           //找到匹配
        else return -1;                     //没有找到
    }

    public static void main(String[] args) {
    
    
        String pat = args[0];
        String txt = args[1];
        KMP kmp = new KMP(pat);
        System.out.println("text:    " + txt);
        int offset = kmp.search(txt);
        System.out.println("pattern: " + pat);
        System.out.println(offset);
    }
}

3.TSTツリー

//基于单词查找树的符号表


import java.util.ArrayList;

public class TST<Value> {
    
    
    private class Node {
    
    
        char c;
        Node left, mid, right;
        Value value;
    }

    private Node root;

    public Value get(String key) {
    
    
        Node x = get(root, key, 0);
        if (x == null) return null;
        return (Value) x.value;
    }

    private Node get(Node x, String key, int d) {
    
    
        if (x == null) return null;
        char c = key.charAt(d);
        if (c < x.c) return get(x.left, key, d);
        else if (c > x.c) return get(x.right, key, d);
        else if (d < key.length() - 1) {
    
    
            return get(x.mid, key, d + 1);
        }
        return x;
    }

    public void put(String key, Value value) {
    
    
        root = put(root, key, value, 0);
    }

    private Node put(Node x, String key, Value value, int d) {
    
    
        char c = key.charAt(d);
        if (x == null) {
    
    
            x = new Node();
            x.c = c;
        }
        if (c < x.c) x.left = put(x.left, key, value, d);
        else if (c > x.c) x.right = put(x.right, key, value, d);
        else if (d < key.length() - 1) {
    
    
            x.mid = put(x.mid, key, value, d + 1);
        } else x.value = value;
        return x;
    }

    //s的最长前缀
    public String longestPrefixOf(String s) {
    
    
        int length = search(root, s, 0, 0);
        return s.substring(0, length);
    }

    public int search(Node x, String s, int length, int d) {
    
    
        if (x == null) return length;
        if (x.value != null) length = d;
        if (d == s.length()) return length;
        char c = s.charAt(d);
        if (c > x.c) return search(x.right, s, length, d + 1);//搜索右子树
        else if (c < x.c) return search(x.left, s, length, d + 1);//搜索左子树
        else return search(x.mid, s, length, d + 1);//搜索中子树
    }

    /*查询词典中所有的单词
     *
     * */
    public ArrayList<String> keys() {
    
    
        ArrayList<String> s = new ArrayList<>();
        s = keysWithPrefix("");
        return s;
    }

    /*
     * 以s为前缀的所有单词的集合
     * */
    public ArrayList<String> keysWithPrefix(String s) {
    
    
        ArrayList<String> arrayList = new ArrayList<>();
        collect(get(root, s, 0), s, arrayList);
        return arrayList;
    }

    public void collect(Node x, String s, ArrayList<String> arrayList) {
    
    
        if (x == null) return;
        s += x.c;
        if (x.value != null) arrayList.add(s);
        collect(x.left, s, arrayList);
        collect(x.mid, s, arrayList);
        collect(x.right, s, arrayList);
    }

    /*
     * 统计键的数目
     * */
    public int size() {
    
    
        return size(root);
    }

    private int size(Node x) {
    
    
        int cnt = 0;
        if (x == null) return 0;
        if (x.value != null) cnt++;              //统计自己这个子树
        cnt += size(x.left);//统计左子树
        cnt += size(x.mid);//统计中子树
        cnt += size(x.right);//统计右子树
        return cnt;
    }
}

おすすめ

転載: blog.csdn.net/fuzekun/article/details/104469470