我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么在Java中实现一个双向匹配分词算法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么在Java中实现一个双向匹配分词算法

本篇文章为大家展示了怎么在Java中实现一个双向匹配分词算法,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

正向最大匹配分词:

该算法是基于分词词典实现,从字符串左侧进行分割匹配,如果词典存在则返回分割出来的词语并将该词从之前的字符串中切除,循环进行切割直到字符串大小为0。

例如:str = "我们都是西北农林科技大学信息工程学院的学生。",(假设我们定义最大切割长度max = 8,也就是八个汉字)

定义分词长度len = max,从左边取出len个字符word = "我们都是西北农林",并在字典中匹配word;
2.字典中没有该词,那么去掉最后一个字符赋值给word,len值减1;
3.重复步骤2,直到在字典中找到该词或是len = 1,退出循环;
4.从str中切除掉已分割的词语,重复进行1、2、3步骤,直到str被分解完。

逆向最大匹配分词:

和正向分词算法一样,只是从字符串的右边开始切分词语,直到字符串长度为0,。这里不再赘述。

双向匹配分词:

该方法是在正向分词和逆向分词的基础上,对于分割有歧义的语句进行歧义分词。提出“贪吃蛇算法”实现。要进行分词的字符串,就是食物。有2个贪吃蛇,一个从左向右吃;另一个从右向左吃。只要左右分词结果有歧义,2条蛇就咬下一口。贪吃蛇吃下去的字符串,就变成分词。 如果左右分词一直有歧义,两条蛇就一直吃。两条蛇吃到字符串中间交汇时,就肯定不会有歧义了。这时候,左边贪吃蛇肚子里的分词,中间没有歧义的分词,右边贪吃蛇肚子里的分词,3个一拼,就是最终的分词结果。

本文是对整段话进行分词,首先将这段话根据标点符号断句,然后将每句话再进行分词输出。

package cn.nwsuaf.spilt;import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Scanner;public class WordSpilt {    private Map<String, Integer> map = new HashMap<String, Integer>();    private int MAX_LENGTH = 5;    public WordSpilt() throws IOException {    BufferedReader br = new BufferedReader(new FileReader("class="lazy" data-src/dict.txt"));    String line = null;    while ((line = br.readLine()) != null) {      line = line.trim();      map.put(line, 0);    }    br.close();  }    public void setMaxLength(int max) {    this.MAX_LENGTH = max;  }    public int getMaxLength() {    return this.MAX_LENGTH;  }    public List<String> spilt(String spiltStr, boolean leftToRight) {    // 如果带切分字符串为空则返回空    if (spiltStr.isEmpty())      return null;    // 储存正向匹配分割字符串    List<String> leftWords = new ArrayList<String>();    // 储存负向匹配分割字符串    List<String> rightWords = new ArrayList<String>();    // 用于取切分的字串    String word = null;    // 取词的长度,初始化设置为最大值    int wordLength = MAX_LENGTH;    // 分词操作中处于字串当前位置    int position = 0;    // 已经处理字符串的长度    int length = 0;    // 去掉字符串中多余的空格    spiltStr = spiltStr.trim().replaceAll("\\s+", "");    // 当待切分字符串没有被切分完时循环切分    while (length < spiltStr.length()) {      // 如果还没切分的字符串长度小于最大值,让取词词长等于该词本身长度      if (spiltStr.length() - length < MAX_LENGTH)        wordLength = spiltStr.length() - length;      // 否则取默认值      else        wordLength = MAX_LENGTH;      // 如果是正向最大匹配,从spiltStr的position处开始切割      if (leftToRight) {        position = length;        word = spiltStr.substring(position, position + wordLength);      }      // 如果是逆向最大匹配,从spiltStr末尾开始切割      else {        position = spiltStr.length() - length;        word = spiltStr.substring(position - wordLength, position);      }      // 从当前位置开始切割指定长度的字符串      // word = spiltStr.substring(position, position + wordLength);      // 如果分词词典里面没有切割出来的字符串,舍去一个字符      while (!map.containsKey(word)) {        // 如果是单字,退出循环        if (word.length() == 1) {          // 如果是字母或是数字要将连续的字母或者数字分在一起          if (word.matches("[a-zA-z0-9]")) {            // 如果是正向匹配直接循环将后续连续字符加起来            if (leftToRight) {              for (int i = spiltStr.indexOf(word, position) + 1; i < spiltStr                  .length(); i++) {                if ((spiltStr.charAt(i) >= '0' && spiltStr                    .charAt(i) <= '9')                    || (spiltStr.charAt(i) >= 'A' && spiltStr                        .charAt(i) <= 'Z')                    || (spiltStr.charAt(i) >= 'a' && spiltStr                        .charAt(i) <= 'z')) {                  word += spiltStr.charAt(i);                } else                  break;              }            } else {              // 如果是逆向匹配,从当前位置之前的连续数字、字母字符加起来并翻转              for (int i = spiltStr.indexOf(word, position - 1) - 1; i >= 0; i--) {                if ((spiltStr.charAt(i) >= '0' && spiltStr                    .charAt(i) <= '9')                    || (spiltStr.charAt(i) >= 'A' && spiltStr                        .charAt(i) <= 'Z')                    || (spiltStr.charAt(i) >= 'a' && spiltStr                        .charAt(i) <= 'z')) {                  word += spiltStr.charAt(i);                  if (i == 0) {                    StringBuffer sb = new StringBuffer(word);                    word = sb.reverse().toString();                  }                } else {                  // 翻转操作                  StringBuffer sb = new StringBuffer(word);                  word = sb.reverse().toString();                  break;                }              }            }          }          break;        }        // 如果是正向最大匹配,舍去最后一个字符        if (leftToRight)          word = word.substring(0, word.length() - 1);        // 否则舍去第一个字符        else          word = word.substring(1);      }      // 将切分出来的字符串存到指定的表中      if (leftToRight)        leftWords.add(word);      else        rightWords.add(word);      // 已处理字符串增加      length += word.length();    }    // 如果是逆向最大匹配,要把表中的字符串调整为正向    if (!leftToRight) {      for (int i = rightWords.size() - 1; i >= 0; i--) {        leftWords.add(rightWords.get(i));      }    }    // 返回切分结果    return leftWords;  }    public boolean isEqual(List<String> list1, List<String> list2) {    if (list1.isEmpty() && list2.isEmpty())      return false;    if (list1.size() != list2.size())      return false;    for (int i = 0; i < list1.size(); i++) {      if (!list1.get(i).equals(list2.get(i)))        return false;    }    return true;  }    public List<String> resultWord(String inputStr) {    // 分词结果    List<String> result = new ArrayList<String>();    // “左贪吃蛇”分词结果    List<String> resultLeft = new ArrayList<String>();    // “中贪吃蛇”(分歧部分)分词结果    List<String> resultMiddle = new ArrayList<String>();    // “右贪吃蛇”分词结果    List<String> resultRight = new ArrayList<String>();    // 正向最大匹配分词结果    List<String> left = new ArrayList<String>();    // 逆向最大匹配分词结果    List<String> right = new ArrayList<String>();    left = spilt(inputStr, true);        right = spilt(inputStr, false);        // 判断两头的分词拼接,是否已经在输入字符串的中间交汇,只要没有交汇,就不停循环    while (left.get(0).length() + right.get(right.size() - 1).length() < inputStr        .length()) {      // 如果正逆向分词结果相等,那么取正向结果跳出循环      if (isEqual(left, right)) {        resultMiddle = left;        break;      }      // 如果正反向分词结果不同,则取分词数量较少的那个,不用再循环      if (left.size() != right.size()) {        resultMiddle = left.size() < right.size() ? left : right;        break;      }      // 如果以上条件都不符合,那么实行“贪吃蛇”算法      // 让“左贪吃蛇”吃下正向分词结果的第一个词      resultLeft.add(left.get(0));      // 让“右贪吃蛇”吃下逆向分词结果的最后一个词      resultRight.add(right.get(right.size() - 1));      // 去掉被“贪吃蛇”吃掉的词语      inputStr = inputStr.substring(left.get(0).length());      inputStr = inputStr.substring(0,          inputStr.length() - right.get(right.size() - 1).length());      // 清理之前正逆向分词结果,防止造成干扰      left.clear();      right.clear();      // 对没被吃掉的字符串重新开始分词      left = spilt(inputStr, true);      right = spilt(inputStr, false);    }    // 循环结束,说明要么分词没有歧义了,要么"贪吃蛇"从两头吃到中间交汇了    // 如果是在中间交汇,交汇时的分词结果,还要进行以下判断:    // 如果中间交汇有重叠了:    // 正向第一个分词的长度 + 反向最后一个分词的长度 > 输入字符串总长度,就直接取正向的    if (left.get(0).length() + right.get(right.size() - 1).length() > inputStr        .length())      resultMiddle = left;    // 如果中间交汇,刚好吃完,没有重叠:    // 正向第一个分词 + 反向最后一个分词的长度 = 输入字符串总长度,那么正反向一拼即可    if (left.get(0).length() + right.get(right.size() - 1).length() == inputStr        .length()) {      resultMiddle.add(left.get(0));      resultMiddle.add(right.get(right.size() - 1));    }    // 将没有歧义的分词结果添加到最终结果result中    for (String string : resultLeft) {      result.add(string);    }    for (String string : resultMiddle) {      result.add(string);    }    // “右贪吃蛇”存储的分词要调整为正向    for (int i = resultRight.size() - 1; i >= 0; i--) {      result.add(resultRight.get(i));    }    return result;  }    public List<String> resultSpilt(String inputStr) {    // 用于存储最终分词结果    List<String> result = new ArrayList<String>();    // 如果遇到标点就分割成若干句话    String regex = "[,。;!?]";    String[] st = inputStr.split(regex);    // 将每一句话的分词结果添加到最终分词结果中    for (String stri : st) {      List<String> list = resultWord(stri);      result.addAll(list);    }    return result;  }  public static void main(String[] args) {    // example:过来看房价贵不贵?乒乓球拍卖完了    Scanner input = new Scanner(System.in);    String str = input.nextLine();    WordSpilt wordSpilt = null;    try {      wordSpilt = new WordSpilt();    } catch (IOException e) {      e.printStackTrace();    }    List<String> list = wordSpilt.resultWord(str);    for (String string : list) {      System.out.print(string + "/");    }  }}

上述内容就是怎么在Java中实现一个双向匹配分词算法,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么在Java中实现一个双向匹配分词算法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

怎么在Java中实现一个双向匹配分词算法

本篇文章为大家展示了怎么在Java中实现一个双向匹配分词算法,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。正向最大匹配分词:该算法是基于分词词典实现,从字符串左侧进行分割匹配,如果词典存在则返回分割
2023-05-30

最大匹配分词算法怎么在Java项目中实现

最大匹配分词算法怎么在Java项目中实现?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。全文检索有两个重要的过程:1分词2倒排索引我们先看分词算法目前对中文分词有两个方向,其
2023-05-31

怎么在java中实现一个gc算法

这期内容当中小编将会给大家带来有关怎么在java中实现一个gc算法,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java可以用来干什么Java主要应用于:1. web开发;2. Android开发;3.
2023-06-14

Java中怎么实现一个TFIDF算法

这篇文章给大家介绍Java中怎么实现一个TFIDF算法,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。算法介绍最近要做领域概念的提取,TFIDF作为一个很经典的算法可以作为其中的一步处理。计算公式比较简单,如下:预处理由
2023-06-02

怎么利用java实现一个二分法算法

这篇文章给大家介绍怎么利用java实现一个二分法算法,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。java 二分法算法1、前提:二分查找的前提是需要查找的数组必须是已排序的,我们这里的实现默认为升序2、原理:将数组分为
2023-05-31

在Java中怎么实现一个快速排序算法

在Java中怎么实现一个快速排序算法?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。快速排序的原理:选择一个关键值作为基准值。比基准值小的都在左边序列(一般是无序
2023-05-30

怎么在java项目中实现一个海盗算法

今天就跟大家聊聊有关怎么在java项目中实现一个海盗算法,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。具体方法如下:package unit4;public class Pirate
2023-05-31

怎么在Android开发中实现一个正则匹配功能

这篇文章给大家介绍怎么在Android开发中实现一个正则匹配功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。在Android开发中,可能也会遇到一下输入框的合法性验证,这时候最常用的就应该是正则表达式去做一些匹配了,
2023-05-31

java中怎么实现一个泛型算法

java中怎么实现一个泛型算法,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。说明1、有界类型参数是实现泛型算法的关键。2、这个方法实现简单但无法编译,因为大于号的操作符(>
2023-06-20

怎么在Android中利用DrawerLayout实现一个双向侧滑菜单

这篇文章将为大家详细讲解有关怎么在Android中利用DrawerLayout实现一个双向侧滑菜单,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。布局文件的代码:
2023-05-30

怎么在react中实现一个diff算法

这期内容当中小编将会给大家带来有关怎么在react中实现一个diff算法,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。单节点Diff单节点Diff比较简单,只有key相同并且type相同的情况才会尝试复用
2023-06-14

怎么在Java项目中实现一个堆排序算法

怎么在Java项目中实现一个堆排序算法?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。堆是数据结构中的一种重要结构,了解“堆”的概念和操作,可以帮助我们快速地掌握堆排序。堆的
2023-05-31

怎么在Java中利用TreeMap实现一个排序算法

怎么在Java中利用TreeMap实现一个排序算法?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。TreeMap 和 HashMap 用法大致相同,但实际需求中,我们需要把一
2023-05-31

怎么在java中利用GUI实现一个加法计算器

怎么在java中利用GUI实现一个加法计算器?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。java基本数据类型有哪些Java的基本数据类型分为:1、整数类型,用来表示整数的数据
2023-06-14

怎么在Java项目中实现一个求逆矩阵算法

这篇文章给大家介绍怎么在Java项目中实现一个求逆矩阵算法,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。实现方法如下:package demo;public class MatrixInverse { public
2023-05-31

Java中怎么实现一个通用组合算法

Java中怎么实现一个通用组合算法,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Java实现通用组合算法,存在一个类似{31311133,33113330}这样的集合,经过
2023-06-17

怎么在java项目中实现一个二叉查找树算法

今天就跟大家聊聊有关怎么在java项目中实现一个二叉查找树算法,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。具体内容如下package 查找;import edu.princeton
2023-05-31

Python中怎么实现一个感知器分类算法

Python中怎么实现一个感知器分类算法,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。感知器算法Perceptron算法是两类(二进制)分类机器学习算法。它是一种神经网络模
2023-06-15

怎么在PHP中实现一个密码散列算法

这期内容当中小编将会给大家带来有关怎么在PHP中实现一个密码散列算法,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。查看密码散列函数的加密算法首先,我们还是看看当前环境中所支持的 password_hash
2023-06-15

怎么在Java中实现一个分页遍历功能

怎么在Java中实现一个分页遍历功能?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1. 数据查询模拟首先mock一个分页获取数据的逻辑,直接随机生成数据,并且控制最多返回三页p
2023-06-06

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录