java如何准确的读取多音字

java准确读取多音字的方法,多音字的识别一直是一个问题,笔者结合了很多不同的读取方法,完成了这个扩展的帮助类。
首先,下载java读取拼音的jar(pinyin4j-2.5.0.jar)。
然后,
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);




文件下载链接:http://download.csdn.net/detail/e_real/8217659

java如何准确的读取多音字的更多相关文章

  1. java的poi技术读取Excel数据到MySQL

    这篇blog是介绍java中的poi技术读取Excel数据,然后保存到MySQL数据中. 你也可以在 : java的poi技术读取和导入Excel了解到写入Excel的方法信息 使用JXL技术可以在 ...

  2. java中的文件读取和文件写出:如何从一个文件中获取内容以及如何向一个文件中写入内容

    import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.Fi ...

  3. java的poi技术读取Excel[2003-2007,2010]

    这篇blog主要是讲述java中poi读取excel,而excel的版本包括:2003-2007和2010两个版本, 即excel的后缀名为:xls和xlsx. 读取excel和MySQL相关: ja ...

  4. java通过文件路径读取该路径下的所有文件并将其放入list中

    java通过文件路径读取该路径下的所有文件并将其放入list中   java中可以通过递归的方式获取指定路径下的所有文件并将其放入List集合中.假设指定路径为path,目标集合为fileList,遍 ...

  5. Java学习-019-Properties 文件读取实例源代码

    在这几天的学习过程中,有开发的朋友告知我,每个编程语言基本都有相应的配置文件支持类,像 Python 编程语言中支持的 ini 文件及其对应的配置文件读取类 ConfigParse,通过这个类,用户可 ...

  6. Java学习-017-EXCEL 文件读取实例源代码

    众所周知,EXCEL 也是软件测试开发过程中,常用的数据文件导入导出时的类型文件之一,此文主要讲述如何通过 EXCEL 文件中 Sheet 的索引(index)或者 Sheet 名称获取文件中对应 S ...

  7. Java学习-016-CSV 文件读取实例源代码

    上文(CSV文件写入)讲述了日常自动化测试过程中将测试数据写入 CSV 文件的源码,此文主要讲述如何从 CSV 文件获取测试过程中所需的参数化数据.敬请各位小主参阅,若有不足之处,敬请大神指正,不胜感 ...

  8. java 文件及流读取

    在Java语言的IO编程中,读取文件是分两个步骤:1.将文件中的数据转换为流,2.读取流内部的数据.其中第一个步骤由系统完成,只需要创建对应的流对象即可,对象创建完成以后步骤1就完成了,第二个步骤使用 ...

  9. java 使用相对路径读取文件

    java 使用相对路径读取文件 1.java project环境,使用java.io用相对路径读取文件的例子: *目录结构:  DecisionTree            |___src      ...

随机推荐

  1. [原创]jQuery的this和$(this)

    网上有很多关于jQuery的this和$(this)的介绍,大多数只是理清了this和$(this)的指向,其实它是有应用场所的,不能一概而论在jQuery调用成员函数时,this就是指向dom对象. ...

  2. Codeforces Gym 100531G Grave 水题

    Problem G. Grave 题目连接: http://codeforces.com/gym/100531/attachments Description Gerard develops a Ha ...

  3. Codeforces Round #335 (Div. 1) C. Freelancer's Dreams 计算几何

    C. Freelancer's Dreams Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.codeforces.com/contes ...

  4. 大话数据结构—平衡二叉树(AVL树)

    平衡二叉树(Self-Balancing Binary Search Tree/Height-Balanced Binary Search Tree),是一种二叉排序树,当中每个节点的左子树和右子树的 ...

  5. SQL Server数据库大型应用解决方案总结

    随着互联网应用的广泛普及,海量数据的存储和访问成为了系统设计的瓶颈问题.对于一个大型的互联网应用,每天百万级甚至上亿的PV无疑对数据库造成了相当高的负载.对于系统的稳定性和扩展性造成了极大的问题. 一 ...

  6. 删除sqlserver2008登录记录

    SQL Server Management Studio登陆窗口 清空这些多余的登陆名 删除SqlStudio.bin文件 WinXP: C:\Documents and Settings\用户文件夹 ...

  7. linux下网络编程常见问题

    网络程序异常退出无core文件产生 这种情况发生在一边连接端已经关闭,但是另外一边还在对连接句柄做send操作,这样做send操作的进程会收到SIGPIPE信号,默认行为是直接退出且不会产生core. ...

  8. 想了解JAVA的,看看(转载)

    较新一篇 / 较旧一篇 编辑 |删除 | 复制链接  公开 想了解JAVA的,看看(转载)2009-03-01 15:41 (分类:默认分类) 先总结一下: J2SE   (Core/Desktop) ...

  9. C# unix时间戳转换

    场景:由于业务需要和java 开发的xxx系统对接日志,xxx系统中用“1465195479100” 来表示时间,C# 里面需要转换做一下逻辑处理,见代码段. C#获取的unix时间戳是10位,原因是 ...

  10. dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了

    dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ); dispatch_group_ ...