zoukankan      html  css  js  c++  java
  • 写一个简单的分词器

    分词器代码

      1 package www.ygh.fenciqiUtils;
      2 
      3 import java.io.FileReader;
      4 import java.util.ArrayList;
      5 import java.util.IdentityHashMap;
      6 import java.util.List;
      7 import java.util.Map;
      8 import java.util.Set;
      9 
     10 /**
     11  * 最终返回的结果:
     12  * 1:表示关键字
     13  * 2:普通的非关键字符串
     14  * 3:整数(暂不支持小数)
     15  * 4:运算符
     16  * 5:分隔符
     17  * @author Administrator
     18  *
     19  */
     20 public class CFenCiQi {
     21     // 初始化集合list1,用于存在关键字
     22     private List<String> list1 = new ArrayList<String>();
     23 
     24     // 定义集合list4,用于存放运算符号
     25     private List<String> list4 = new ArrayList<String>();
     26 
     27     // 定义集合list5,用于存放分用于存放分隔符号
     28     private List<String> list5 = new ArrayList<String>();
     29 
     30     // 定义集合list3
     31     private List<String> list3 = new ArrayList<String>();
     32     
     33     //"C:\Users\Administrator\Desktop\test_c.c"
     34     private String filePath;
     35 
     36     private  List<Map<String, String>> mapList = new ArrayList<Map<String, String>>();
     37 
     38     private int temp = 0;
     39 
     40     private int match_1 = 0;
     41 
     42     private int match_4 = 0;
     43 
     44     private int match_3 = 0;
     45     
     46     private int ch = 0;
     47     private String str1 = "";
     48     
     49     public CFenCiQi(String filePath) {
     50         this.filePath = filePath;
     51     }
     52     
     53     
     54 
     55     public CFenCiQi() {
     56         
     57     }
     58 
     59 
     60     /**
     61      * 初始化关键字,运算符,分隔符等list集合
     62      */
     63     public void init() {
     64 
     65         // 初始化集合list1,用于存在关键字
     66         list1.add("if");
     67         list1.add("int");
     68         list1.add("for");
     69         list1.add("while");
     70         list1.add("do");
     71         list1.add("return");
     72         list1.add("break");
     73         list1.add("continue");
     74 
     75         // 初始化集合list4,用于存放运算符号
     76         list4.add("+");
     77         list4.add("-");
     78         list4.add("*");
     79         list4.add("/");
     80         list4.add("=");
     81         list4.add(" ");
     82         list4.add("<");
     83         list4.add(" =");
     84         list4.add("<=");
     85         list4.add("!=");
     86 
     87         // 初始化集合list5,用于存放分隔符号
     88         list5.add(",");
     89         list5.add(";");
     90         list5.add("{");
     91         list5.add("}");
     92         list5.add("(");
     93         list5.add(")");
     94 
     95         // 初始化集合list3,用于存放数组字符
     96         list3.add("0");
     97         list3.add("1");
     98         list3.add("2");
     99         list3.add("3");
    100         list3.add("4");
    101         list3.add("5");
    102         list3.add("6");
    103         list3.add("7");
    104         list3.add("8");
    105         list3.add("9");
    106 
    107     }
    108 
    109     /**
    110      * 判断字符是否和运算符匹配
    111      * @param c
    112      * @return
    113      */
    114     public boolean match_2(String c) {
    115         for (String str : list4) {
    116             if (c.equals(str)) {
    117                 return true;
    118             }
    119         }
    120         return false;
    121     }
    122 
    123     /**
    124      * 判断字符是否和分隔符匹配
    125      * @param c
    126      * @return
    127      */
    128     public boolean match_4(String c) {
    129         for (String str : list5) {
    130             if (c.equals(str)) {
    131                 return true;
    132             }
    133         }
    134         return false;
    135     }
    136 
    137     /**
    138      * 判断读取的字符是否和数字匹配
    139      * @param c
    140      * @return
    141      */
    142     public boolean match_3(String c) {
    143         for (String str : list3) {
    144             if (c.equals(str)) {
    145                 return true;
    146             }
    147         }
    148         return false;
    149     }
    150 
    151     /**
    152      * 进行分词
    153      * @throws Exception
    154      */
    155     public void getFenCi() throws Exception {
    156         
    157         
    158         //读取文件的路径
    159         FileReader fileReader = new FileReader(filePath);
    160         //挨个读取字符
    161         while ((ch = fileReader.read()) != -1) {
    162 
    163             char c = (char) ch;
    164             if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
    165 
    166                 if (match_4 == 1) {
    167                     matchEqual_4();
    168                 }
    169 
    170                 if (match_3 == 1) {
    171                     matchEqual_3();
    172                 }
    173 
    174                 str1 = str1 + c;
    175                 match_1 = 1;
    176                 
    177             } else if (match_4(c + "")) {
    178                 if(match_1==1){
    179                     matchEqual_1();
    180                 }
    181 
    182                 if (match_4 == 1) {
    183                     matchEqual_4();
    184 
    185                 }
    186 
    187                 if (match_3 == 1) {
    188                     matchEqual_3();
    189                 }
    190 
    191                 str1 = "";
    192                 str1 = str1 + c;
    193                 setValue("5", str1);
    194                 str1 = "";
    195 
    196             } else if (match_2(c + "")) {
    197                 if(match_1==1){
    198                     matchEqual_1();
    199                 }
    200 
    201                 if (match_3 == 1) {
    202                     matchEqual_3();
    203                 }
    204 
    205                 str1 = str1 + c;
    206                 match_4 = 1;
    207 
    208             } else if (match_3(c + "")) {
    209                 if(match_1==1){
    210                     matchEqual_1();
    211                 }
    212 
    213                 if (match_4 == 1) {
    214                     matchEqual_4();
    215                 }
    216 
    217                 str1 = str1 + c;
    218                 match_3 = 1;
    219             }
    220         }
    221         fileReader.close();
    222     }
    223 
    224     /**
    225      * 设置集合里面的值
    226      * @param id
    227      * @param value
    228      */
    229     public void setValue(String id, String value) {
    230         Map<String, String> fenci = new IdentityHashMap<String, String>();
    231         fenci.put(id, value);
    232         mapList.add(fenci);
    233     }
    234 
    235     public void matchEqual_1() {
    236             temp = 0;
    237             for (String str : list1) {
    238                 if (str.equals(str1)) {
    239                     setValue("1", str1);
    240                     temp = 1;
    241                     break;
    242                 }
    243             }
    244 
    245             if (temp == 0) {
    246                 setValue("2", str1);
    247             }
    248 
    249             match_1 = 0;
    250             str1 = "";
    251     }
    252     
    253     /**
    254      * 字符串为数字的处理方法
    255      */
    256     public void matchEqual_3() {
    257         setValue("3", str1);
    258         match_3 = 0;
    259         str1 = "";
    260     }
    261     
    262     /**
    263      * 字符串为运算符的处理方法
    264      */
    265     public void matchEqual_4() {
    266         setValue("4", str1);
    267         match_4 = 0;
    268         str1 = "";
    269     }
    270 
    271     
    272     /**
    273      * 使用默认的分词器,默认支持c语言
    274      * @return
    275      * @throws Exception
    276      */
    277     public List<Map<String, String>> getResult() throws Exception {
    278         //如果没有实现自定义分词,那么就使用默认分词,如果有,实现自定义分词
    279         if(this.list1==null || this.list4==null || this.list5 ==null){
    280             init();
    281         }
    282         getFenCi();
    283         return this.mapList;
    284     }
    285         
    286     
    287     /**
    288      * 对封装的分词结果进行专业的toSting
    289      * @param mapList1
    290      */
    291     public static void getString(List<Map<String, String>> mapList1){
    292         for(Map<String, String> map:mapList1){
    293             Set<String> keySet = map.keySet();
    294             for(String key:keySet){
    295                 System.out.print("{"+key+"-->"+map.get(key)+"}");
    296             }
    297             System.out.print(",");
    298         }
    299         System.out.println();
    300     }
    301 
    302     /**
    303      * 设置需要分词源文件的路径
    304      * @param filePath
    305      */
    306     public void setFilePath(String filePath) {
    307         this.filePath = filePath;
    308     }
    309     
    310     /**
    311      * 指定分词的关键字,运算符和分隔符,帮你分词
    312      * @param keyList 指定关键字的集合
    313      * @param calculateList     指定运算符集合
    314      * @param sperateList       指定分隔符集合
    315      */
    316     public void setDefaultParam(List<String> keyList,List<String> calculateList,List<String> separateList){
    317         this.list1 = keyList;
    318         this.list4 = calculateList;
    319         this.list5 = separateList;
    320     }
    321     
    322     
    323 
    324 }

    分词器测试代码

    package www.ygh.test;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    
    import org.junit.Test;
    
    import www.ygh.fenciqiUtils.CFenCiQi;
    
    public class Test_FenCiQi {
    
        // 初始化集合list1,用于存在关键字
        private List<String> list1 = new ArrayList<String>();
    
        // 定义集合list4,用于存放运算符号
        private List<String> list4 = new ArrayList<String>();
    
        // 定义集合list5,用于存放分用于存放分隔符号
        private List<String> list5 = new ArrayList<String>();
    
        // c语言源代码路径
        public String filePath = "C:\Users\Administrator\Desktop\test_c.c";
    
        // java语言源代码路径
        public String filePath2 = "C:\Users\Administrator\Desktop\fenci.java";
    
        /**
         * 使用系统默认的分词,只支持c语言
         * 
         * @throws Exception
         */
        @Test
        public void test_1() throws Exception {
            // 创建分词器对象
            CFenCiQi cFenCiQi = new CFenCiQi();
            // 设置源代码路径
            cFenCiQi.setFilePath(filePath);
            // 进行分词,并且获取结果
            List<Map<String, String>> mapList = cFenCiQi.getResult();
            System.out.println(mapList.size());
            CFenCiQi.getString(mapList);
        }
    
        /**
         * 测试自定义的c语言分词
         * 
         * @throws Exception
         */
        @Test
        public void test_2() throws Exception {
            //初始化c语言的分词条件
            fun1();
            // 创建分词器对象
            CFenCiQi cFenCiQi = new CFenCiQi();
            //把自定义的分词条件传入
            cFenCiQi.setDefaultParam(list1, list4, list5);
            //传入源代码路径
            cFenCiQi.setFilePath(filePath);
            List<Map<String, String>> mapList = cFenCiQi.getResult();
            CFenCiQi.getString(mapList);
        }
    
        /**
         * 测试自定义的java的分词
         * 
         * @throws Exception
         */
        @Test
        public void test_3() throws Exception {
            fun2();
            CFenCiQi cFenCiQi = new CFenCiQi();
            cFenCiQi.setDefaultParam(list1, list4, list5);
            cFenCiQi.setFilePath(filePath2);
            List<Map<String, String>> mapList = cFenCiQi.getResult();
            CFenCiQi.getString(mapList);
        }
    
        /**
         * 初始化c语言分词条件
         */
        public void fun1() {
    
            // 初始化集合list1,用于存c语言在关键字
            list1.add("if");
            list1.add("int");
            list1.add("for");
            list1.add("while");
            list1.add("do");
            list1.add("return");
            list1.add("break");
            list1.add("continue");
    
            // 初始化集合list4,用于c语言存放运算符号
            list4.add("+");
            list4.add("-");
            list4.add("*");
            list4.add("/");
            list4.add("=");
            list4.add(" ");
            list4.add("<");
            list4.add(" =");
            list4.add("<=");
            list4.add("!=");
    
            // 初始化集合list5,用于存放c语言分隔符号
            list5.add(",");
            list5.add(";");
            list5.add("{");
            list5.add("}");
            list5.add("(");
            list5.add(")");
    
        }
    
        /**
         * 初始化java的分词条件
         */
        public void fun2() {
    
            // 初始化集合list1,用于存在java关键字
            list1.add("if");
            list1.add("int");
            list1.add("for");
            list1.add("while");
            list1.add("do");
            list1.add("return");
            list1.add("break");
            list1.add("public");
            list1.add("class");
            list1.add("void");
            list1.add("list");
            list1.add("out");
            list1.add("static");
            list1.add("new");
            list1.add("char");
            list1.add("private");
            list1.add("this");
            list1.add("import");
            list1.add("package");
    
            // 初始化集合list4,用于java存放运算符号
            list4.add("+");
            list4.add("-");
            list4.add("*");
            list4.add("/");
            list4.add("=");
            list4.add(" ");
            list4.add("<");
            list4.add(" =");
            list4.add("<=");
            list4.add("!=");
    
            // 初始化集合list5,用于存放java分隔符号
            list5.add(",");
            list5.add(";");
            list5.add("{");
            list5.add("}");
            list5.add("(");
            list5.add(")");
    
        }
    }

    只是一个简单的实现,还有很多不足的地方,希望大家帮忙提提意见,修改修改

  • 相关阅读:
    漫话JavaScript与异步·第三话——Generator:化异步为同步
    HTTPS、证书与使用Charles抓包
    【前端基础】动态脚本与JSONP
    前端十万个为什么(之一):我们为什么需要npm?
    一个前端程序员的费曼技巧练习
    漫话JavaScript与异步·第二话——Promise:一诺千金
    漫话JavaScript与异步·第一话——异步:何处惹尘埃
    Flex:CSS3布局利器
    BFC探秘
    虚机的部分操作
  • 原文地址:https://www.cnblogs.com/yghjava/p/5893137.html
Copyright © 2011-2022 走看看