java对ac_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 queue = new LinkedList();

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;

}

}

}

运行截图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值