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

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 block
			e.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;
		}
	}
	

}

运行截图:

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


    原文作者:Trie树
    原文地址: https://blog.csdn.net/simon_world/article/details/40373063
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注