DFA状态机解析字符串

来源:互联网 发布:迅雷mac版磁力链接 编辑:程序博客网 时间:2024/05/12 02:45

假如有这么一个需求。

解析一段字符串中指定字符后面的两个字符并且。

如下:解析以下所有“%”(百分号)后的两个字符,并且这两个字符中不能包含“%”本身。

%中国%人民银行%%AB&%C%DE%F

返回结果如下:

[中国, 人民, AB, DE]

接下来我使用JDK自带的工具和DFA各自实现一下该功能。

package com.kevin.test;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.StringTokenizer;/** * 使用状态机思想解析字符 *  */public class MyTest {/** * 解析字符串中%后面两个字符 *  * @param args */public static void main(String[] args) {long start = System.currentTimeMillis();long total = 1000000;int i = 0;String source = "%中国%人民银行%%AB&%C%DE%F";char splitChar = '%';while (i < total) {useDFA(source, splitChar);i++;}System.out.println("useDFA--->>" + useDFA(source, splitChar) + "    use time:" + (System.currentTimeMillis() - start));start = System.currentTimeMillis();i = 0;while (i < total) {useJDKTools(source, splitChar);i++;}System.out.println("useJDKTools--->>" + useJDKTools(source, splitChar) + " use time:" + (System.currentTimeMillis() - start));}public static String useJDKTools(String str, char chat) {StringTokenizer tokenizer = new StringTokenizer(str, String.valueOf(chat));List<String> list = new ArrayList<String>();while (tokenizer.hasMoreTokens()) {String token = tokenizer.nextToken();if (token != null && token.length() >= 2) {list.add(token.substring(0, 2));}}return Arrays.toString(list.toArray());}public static String useDFA(String str, char chat) {List<String> codes = new ArrayList<String>();Status currentState = null;char c1 = '\0';char c2 = '\0';for (int i = 0; i < str.length(); i++) {char currentChar = str.charAt(i);if (currentChar == chat) {if (currentState == Status.SECOND) {char[] s1 = { c1, c2 };codes.add(new String(s1));}currentState = Status.DONE;} else if (currentState == Status.DONE) {c1 = currentChar;currentState = Status.FIRST;} else if (currentState == Status.FIRST) {c2 = currentChar;currentState = Status.SECOND;} else if (currentState == Status.SECOND) {char[] s1 = { c1, c2 };codes.add(new String(s1));currentState = null;}}if (currentState == Status.SECOND) {char[] s1 = { c1, c2 };codes.add(new String(s1));}return Arrays.toString(codes.toArray());}public enum Status {DONE, FIRST, SECOND;}}

最后运行MAIN 方法使用两种方式各自循环执行1000000次

执行时间如下:

useDFA--->>[中国, 人民, AB, DE]    use time:423(毫秒)

useJDKTools--->>[中国, 人民, AB, DE] use time:596(毫秒)

从这个简单的DEMO对状态机思想有了一个初步的认识。


接下来实现一个敏感词过滤。

代码下载地址:

http://download.csdn.net/detail/kevin_luan/7322435




0 0
原创粉丝点击