import java.util.*; public class Main{ public static void main(String[] args){ String S = "yasherhs"; String[] words = {"say","she","shr","he","her","hs"}; System.out.println(numMatchingSubseq(S,words)); } public static int numMatchingSubseq(String S, String[] words) { int len = words.length; Node root = new Node(0); for(int i=0;i<len;i++){ insert(root,words[i]); } adjustFail(root); char[] c = S.toCharArray(); len = c.length; int result = 0; Node temp = root; for(int i=0;i<len;){ int num = c[i]-‘a‘; if(temp==root && temp.child[num]==null){ i++; continue; } if(temp.child[num]!=null){ result += temp.child[num].count; temp = temp.child[num]; i++; }else{ temp = temp.fail; result+= temp.count; } } return result; } private static void insert(Node root,String s){ int len = s.length(); char[] c = s.toCharArray(); Node temp = root; for(int i=0;i<len;i++){ if(temp.child[c[i]-‘a‘]==null){ temp.child[c[i]-‘a‘] = new Node(c[i]-‘a‘); temp.child[c[i]-‘a‘].parent = temp; } temp = temp.child[c[i]-‘a‘]; } temp.count++; } private static void adjustFail(Node root){ Queue<Node> queue = new LinkedList<>(); for(int i=0;i<26;i++){ if(root.child[i]==null){ continue; } root.child[i].fail = root; queue.add(root.child[i]); } while(queue.size()!=0){ Node node = queue.poll(); for(int i=0;i<26;i++){ if(node.child[i]!=null){ node.child[i].fail = root; Node fail = node.fail; while(fail!=null){ if(fail.child[node.child[i].value]!=null){ node.child[i].fail = fail.child[node.child[i].value]; break; }else{ fail = fail.fail; } } queue.add(node.child[i]); } } } } private static void print(Node root){ Node temp = root; for(int i=0;i<26;i++){ if(root.child[i]!=null){ System.out.print(i+"&"+root.child[i].fail.value+" "); print(root.child[i]); } } System.out.println(); } } class Node{ Node[] child; Node parent; Node fail; int value; int count; public Node(int value){ this.count = 0; this.child = new Node[26]; this.value = value; } }
原文:https://www.cnblogs.com/xinyi-blog/p/9678284.html