AC 算法的trie树实现(java版)

来源:互联网 发布:手机淘宝图片很模糊 编辑:程序博客网 时间:2024/04/28 04:28

AC 算法的一种实现(java版)

前言:

AC算法是最早也是最著名的多模式匹配算法。关于AC算法的讲解的文章很多,这里不再赘述。网上实现的大多数是用C或C++,现在给出java的实现。代码均为作者原创,仅供初学者参考,转载请注明出处。

代码实现:

package com.ac;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.PrintStream;import java.util.LinkedList;import java.util.Scanner;import java.util.Queue;public class Ac {/** * the member variable  */public final static int STATE = 1024;public final static int CHARACTER = 26;public static int[][] go;public static String[] outPut;public static int[] fail;public static int curState;private static PrintStream ps_goTo;private static PrintStream ps_Output;private static PrintStream ps_fail;/** *  * @param args test Ac */public static void main(String[] args) {goTo("Pattern.txt");bulidFail();acSearch();}/** * to build goto * @param filename Pattern.txt */private static void goTo(String filename){go = new int [STATE][CHARACTER];outPut = new String[STATE];for(int i = 0; i < STATE; i++) {outPut[i] = new String("");}curState = 0;try {Scanner in = new Scanner(new File(filename));while(in.hasNextLine()) {String pattern = in.next();if(!pattern.equals("\n")) {char[] tempChar = pattern.toCharArray();int curPattern = 0;for(int i = 0; i < tempChar.length; i++) {if(go[curPattern][hash(tempChar[i])] == 0) {curState++;go[curPattern][hash(tempChar[i])] = curState;curPattern = curState;} else {curPattern = go[curPattern][hash(tempChar[i])];}}outPut[curPattern] = new String(" " + pattern );}}in.close();} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} File goTo = new File("goTo.txt");try {ps_goTo = new PrintStream(new FileOutputStream(goTo));for(int i = 0; i < STATE; i++) {for(int j = 0; j < CHARACTER; j++) {if(go[i][j] != 0) {String temp = "go[" + i + "]" + "[" + (char)(j + 97) + "]" + " = " + go[i][j];ps_goTo.print(temp + "\n");}}}ps_goTo.close();} catch (FileNotFoundException e) {e.printStackTrace();}}/** * to bulid fail */private static void bulidFail() {Queue<Integer> queue = new LinkedList<Integer>();fail = new int[STATE];for(int i = 0; i < CHARACTER; i++) {if(go[0][i] != 0) {queue.add(go[0][i]);fail[i] = 0;}}while(!queue.isEmpty()) {int r = queue.remove();for(int i = 0; i < CHARACTER; i++) {int state;int s;if(go[r][i] != 0) {s = go[r][i];queue.add(s);state = fail[r];fail[s] = go[state][i];outPut[s] = outPut[s] + outPut[fail[s]];}}}File output = new File("Output.txt");File Fail = new File("fail.txt");try {ps_Output = new PrintStream(new FileOutputStream(output));ps_fail = new PrintStream(new FileOutputStream(Fail));for(int i = 0; i <= curState; i++) {if(!outPut[i].isEmpty()) {String temp = "output[" + i +"] = " + outPut[i] + "\n";ps_Output.print(temp);}}for(int i = 1; i <= curState; i++){String temp = "fail[" + i + "] = " + fail[i] + "\n";ps_fail.print(temp);}ps_Output.close();ps_fail.close();} catch (FileNotFoundException e) {e.printStackTrace();}}private static void acSearch() {while(true) {System.out.println("请选择功能:");System.out.println("1.查询匹配");System.out.println("2.退出");String choose;String pattern;int state;Scanner in = new Scanner(System.in);choose = in.next();switch(choose) {case "1":state = 0;System.out.println("请输入要查询的字符串:");pattern = in.next();char[] temp = pattern.toCharArray();for(int i = 0; i < pattern.length(); i++) {if(go[state][hash(temp[i])] == 0) {state = fail[state];} else {state = go[state][hash(temp[i])];}if(!outPut[state].equals("")) {System.out.println("关键字出现的位置是:" + (i+1));System.out.println("匹配的模式段是:" + outPut[state] + "\n");}}break;case "2":in.close();System.exit(0);break;default:System.out.println("输入错误!");System.exit(-1);}}}/** * @param c the converting character * @return int  */private static int hash(char c) {if(c >= 65 && c <= 90 ) {return c - 65;} else if (c >= 97 && c <= 122) {return c - 97;}else {return 0;}}}

运行截图:



0 0