java如何准确的读取多音字
package data.util; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination; public class PinyinUtilsPro {
private static Map<String, List<String>> pinyinMap = new HashMap<String, List<String>>(); private static List<String> pinyin = new ArrayList<String>();
private static List<String> hpinyin = new ArrayList<String>(); private static String regx = "(,| |\\[|\\])";// 正则表达式,匹配字符串用 public static void main(String[] args) {
String str = "绿色中国银行长沙分行"; convertChineseToPinyin(str);
String py = getPinyin();
System.out.println(str + " = " + py); String headP = getHeadPinyin();
System.out.println(headP);
} public static String getPinyin(){
return String.valueOf(pinyin).replaceAll(regx, "");
} public static String getHeadPinyin(){
return String.valueOf(hpinyin).replaceAll(regx, "");
} /**
* 汉字转拼音 最大匹配优先
*
* @param chinese
* @return
*/
public static void convertChineseToPinyin(String chinese) {
initPinyin();
HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
defaultFormat.setVCharType(HanyuPinyinVCharType.WITH_V);
defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE); char[] arr = chinese.toCharArray(); for (int i = 0; i < arr.length; i++) {
char ch = arr[i];
if (ch > 128) { // 非ASCII码
// 取得当前汉字的所有全拼
try {
String[] results = PinyinHelper.toHanyuPinyinStringArray(
ch, defaultFormat);
if (results != null) { // 非中文
int len = results.length;
if (len == 1) { // 不是多音字
setValue(results[0]);
} else { // 多音字
// 合并同音不同声调(去重)
List<String> duoyinziPinyins= new ArrayList<String>();// 定义一个空的数组
for(int k=0;k<len;k++){
if(!duoyinziPinyins.contains(results[k])){
duoyinziPinyins.add(results[k]);
}
} if(duoyinziPinyins.size()==1){
setValue(duoyinziPinyins.get(0));// 如果新的集合长度是1,就取第一个
}else{//
System.out.println("多音字:" + ch);
int length = chinese.length();
boolean flag = false;
for (int x = 0; x < duoyinziPinyins.size(); x++) {
String py = duoyinziPinyins.get(x); if (i + 3 <= length) { // 后向匹配2个汉字 大西洋
if(matchPinyins(py,chinese, i, i+3)){
flag = setValue(py);
break;
}
} if (i + 2 <= length) { // 后向匹配 1个汉字 大西
if(matchPinyins(py,chinese, i, i+2)){
flag = setValue(py);
break;
}
} if ((i - 2 >= 0) && (i + 1 <= length)) { // 前向匹配2个汉字
if(matchPinyins(py,chinese, i-2, i+1)){
flag = setValue(py);
break;
}
} if ((i - 1 >= 0) && (i + 1 <= length)) { // 前向匹配1个汉字
// 固大
if(matchPinyins(py,chinese, i-1, i+1)){
flag = setValue(py);
break;
}
} if ((i - 1 >= 0) && (i + 2 <= length)) { // 前向1个,后向1个
// 固大西
if(matchPinyins(py,chinese, i-1, i+2)){
flag = setValue(py);
break;
}
}
} if (!flag) {
// 如果都没有找到,也就是常用读音
System.out.println("default = " + duoyinziPinyins.get(0));
setValue(duoyinziPinyins.get(0));
}
}
}
}
} catch (BadHanyuPinyinOutputFormatCombination e) {
e.printStackTrace();
}
} else {
setValue(String.valueOf(ch));
}
}
} // 截取词组,并匹配拼音表中的词组
private static boolean matchPinyins(String py,String chinese,int m,int n){
String s = chinese.substring(m,n);
List<String> cizus = pinyinMap.get(py);
if(cizus!=null&&cizus.contains(s)){
return true;
}
return false;
} private static boolean setValue(String py) {
pinyin.add(py);
hpinyin.add(py.substring(0, 1));
return true;
} /**
* 初始化 所有的多音字词组
*/
public static void initPinyin() {
// 读取多音字的全部拼音表;
InputStream file = PinyinUtilsPro.class.getResourceAsStream("/duoyinzi_dic.txt");
BufferedReader br = null;
String s = null;
try {
br = new BufferedReader(new InputStreamReader(file,"UTF-8"));
while ((s = br.readLine()) != null) {
if (s != null) {
String[] arr = s.split("#");
String pinyin = arr[0];
String chinese = arr[1]; if (chinese != null) {
String[] strs = chinese.split(" ");
//去空
List<String> list = arr2List(strs);
pinyinMap.put(pinyin, list);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} // 数组转换成集合,并且去掉空格
private static List<String> arr2List(String[] strs) {
if(strs!=null&&strs.length>0){
List<String> list = new ArrayList<String>();
for (int i = 0; i < strs.length; i++) {
if(!"".equals(strs[i].trim())){
list.add(strs[i].trim());
}
}
return list;
}else{
return null;
}
}
}
使用方法:
PinyinUtilsPro.convertChineseToPinyin(s);
String itemHeadpell = PinyinUtilsPro.getHeadPinyin();
String itemAspell = PinyinUtilsPro.getPinyin();
sysDicItem.setItemSpell(itemHeadpell);
sysDicItem.setItemAspell(itemAspell);
java如何准确的读取多音字的更多相关文章
- java的poi技术读取Excel数据到MySQL
这篇blog是介绍java中的poi技术读取Excel数据,然后保存到MySQL数据中. 你也可以在 : java的poi技术读取和导入Excel了解到写入Excel的方法信息 使用JXL技术可以在 ...
- java中的文件读取和文件写出:如何从一个文件中获取内容以及如何向一个文件中写入内容
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.Fi ...
- java的poi技术读取Excel[2003-2007,2010]
这篇blog主要是讲述java中poi读取excel,而excel的版本包括:2003-2007和2010两个版本, 即excel的后缀名为:xls和xlsx. 读取excel和MySQL相关: ja ...
- java通过文件路径读取该路径下的所有文件并将其放入list中
java通过文件路径读取该路径下的所有文件并将其放入list中 java中可以通过递归的方式获取指定路径下的所有文件并将其放入List集合中.假设指定路径为path,目标集合为fileList,遍 ...
- Java学习-019-Properties 文件读取实例源代码
在这几天的学习过程中,有开发的朋友告知我,每个编程语言基本都有相应的配置文件支持类,像 Python 编程语言中支持的 ini 文件及其对应的配置文件读取类 ConfigParse,通过这个类,用户可 ...
- Java学习-017-EXCEL 文件读取实例源代码
众所周知,EXCEL 也是软件测试开发过程中,常用的数据文件导入导出时的类型文件之一,此文主要讲述如何通过 EXCEL 文件中 Sheet 的索引(index)或者 Sheet 名称获取文件中对应 S ...
- Java学习-016-CSV 文件读取实例源代码
上文(CSV文件写入)讲述了日常自动化测试过程中将测试数据写入 CSV 文件的源码,此文主要讲述如何从 CSV 文件获取测试过程中所需的参数化数据.敬请各位小主参阅,若有不足之处,敬请大神指正,不胜感 ...
- java 文件及流读取
在Java语言的IO编程中,读取文件是分两个步骤:1.将文件中的数据转换为流,2.读取流内部的数据.其中第一个步骤由系统完成,只需要创建对应的流对象即可,对象创建完成以后步骤1就完成了,第二个步骤使用 ...
- java 使用相对路径读取文件
java 使用相对路径读取文件 1.java project环境,使用java.io用相对路径读取文件的例子: *目录结构: DecisionTree |___src ...
随机推荐
- Codeforces Beta Round #5 E. Bindian Signalizing 并查集
E. Bindian Signalizing Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset ...
- wordpress文章ID不连续显示问题的完美解决
在最新版的 wordpress 系统中,依然存在着文章ID不连续显示的问题,也就是我们还没有上传多少文章,在数据库里的ID号已经很大了,也就是说如果我们的博客使用的是固定链接,那么在前台显示的ID相差 ...
- [Angular2 Router] Style the Active Angular 2 Navigation Element with routerLinkActive
You can easily show the user which route they are on using Angular 2’s routerLinkActive. Whenever a ...
- SQL Server如何截断(Truncate)和收缩(Shrink)事务日志
当SQL Server截断事务日志时,它仅仅是在虚拟日志文件中做个标记,以便不再使用它,然后准备以重用形式来做备份(假如运载在完整或是批量日志恢复模型).也就是说,在使用简单恢复模型时,事务日志包括如 ...
- 深入解析 ext2 文件系统
很久以来,就想写一篇关于ext 家族文件系统的文章,源于我刚工作的时候,曾经一不小心rm -rf,误删除了很多文件,当时真想有个数据恢复软件能帮我把数据回复了.当然学习数据恢复,首先要学习文件系统. ...
- java中的链式编程
听到链式编程听陌生的,但是写出来就感觉其实很熟悉 package test; public class Test { String name; String phone; String mail; S ...
- Remoting
一. Remoting基础 什么是Remoting,简而言之,我们可以将其看作是一种分布式处理方式.从微软的产品角度来看,可以说Remoting就是DCOM的一种升级,它改善了很多功能,并极 ...
- SQL Server 的事务和锁(一)
最近在项目中进行压力测试遇到了数据库的死锁问题,简言之,如下的代码在 SERIALIZABLE 隔离级别造成了死锁: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 SELECT @ ...
- C#基础--局部类型Partial
局部类型 原本来在同一个命名(namespace)空间下 是不允许相同的类(class)名存在的 但是partial关键字可以允许在同一个namespace下有想通过的类名存在 写法 下面的两个不 ...
- Linux下mongodb安装
1>设置mongoDB目录 cd /home/apps 附:centOS下创建目录命令 mkdir /home/apps 2>下载mongodb curl -O http:// ...