介绍

Pinyin4j是一个流行的Java库,支持中文字符和拼音之间的转换。拼音输出格式可以定制,然而真正的把含有多音字、数字、字母的中文句子转成拼音得到所有的组合情况却有很大难度,我看过很多有关博客或者帖子,被广大网友视为它的短板和不足,很多网友哀声叹气不能真正得到所有组合情况,一部分也只是用简单循环得到中文句子的拼音组合情况的一种,鄙人利用业余时间研究了研究,把研究结果分享 出来,下边将带大家循序渐进把含有多音字、数字、字母的中文句子转成拼音得到所有的组合情况。

最简单方式获取汉字的拼音

[java] view plain copy
  1. char word='长';//待测汉字,多音字
  2. /*直接获取拼音,返回字符串数组,可能有多个,注意:如果传入的非汉字则返回null*/
  3. String[] easyPinyin=PinyinHelper.toHanyuPinyinStringArray(word);
  4. for(String s:easyPinyin){
  5. System.out.println("汉字转拼音最简单方式:"+s);//有2个zhang3,chang2,后边的数字代表音调
  6. }

运行结果如下:

[java] view plain copy
  1. 汉字转拼音最简单方式:zhang3
  2. 汉字转拼音最简单方式:chang2

以指定的拼音格式获取汉字的拼音

[java] view plain copy
  1. HanyuPinyinOutputFormat pinyinFormat = new HanyuPinyinOutputFormat(); //创建拼音输入格式类
  2. pinyinFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);//指定格式中的大小写属性为小写
  3. pinyinFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);//指定音标格式无音标
  4. pinyinFormat.setVCharType(HanyuPinyinVCharType.WITH_V);//指定用v表示ü
  5. String[] formatPinyin=null;
  6. try {
  7. formatPinyin = PinyinHelper.toHanyuPinyinStringArray(word, pinyinFormat);//获取对应的汉字拼音,不是汉字返回null
  8. } catch (BadHanyuPinyinOutputFormatCombination e) {//会抛出异常,捕获异常
  9. //logger.error(e.getMessage());
  10. e.printStackTrace();
  11. }
  12. for(String s:formatPinyin){
  13. System.out.println("格式化后的汉字转拼音结果:"+s);//有2个zhang3,chang2,后边的数字代表音调
  14. }

运行结果:

[java] view plain copy
  1. 格式化后的汉字转拼音结果:zhang
  2. 格式化后的汉字转拼音结果:chang

使用循环获取包含汉字的一段文字的拼音(只能获取一种情况)

先定义2个方法,如下:

[java] view plain copy
  1. /**
  2. * 获取包含汉字的一段文字的拼音(只获取一种情况),注意如果涉及汉字的多个读音只获取一种,不全部罗列出来
  3. */
  4. public static String getEasyPinyins(String s){
  5. if(s==null){
  6. s="";//防止为null,后边处理时报错
  7. }
  8. StringBuilder sb=new StringBuilder();
  9. char[] words=s.toCharArray();//把这段文字转成字符数组
  10. for(char c:words){
  11. sb.append(Pinyin4jTest.getPinyin(c));
  12. }
  13. return sb.toString();//转化成字符串返回
  14. }
  15. /**
  16. * 获取一个字符的拼音(多音字则返回一种情况),非汉字则返回字符本身
  17. */
  18. public static String getPinyin(char word){
  19. HanyuPinyinOutputFormat pinyinFormat = new HanyuPinyinOutputFormat();   //创建拼音输入格式类
  20. pinyinFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);//指定格式中的大小写属性为小写
  21. pinyinFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);//指定音标格式无音标
  22. pinyinFormat.setVCharType(HanyuPinyinVCharType.WITH_V);//指定用v表示ü
  23. String[] formatPinyin=null;
  24. try {
  25. formatPinyin = PinyinHelper.toHanyuPinyinStringArray(word, pinyinFormat);//获取对应的汉字拼音,不是汉字返回null
  26. } catch (BadHanyuPinyinOutputFormatCombination e) {//会抛出异常,捕获异常
  27. //logger.error(e.getMessage());
  28. e.printStackTrace();
  29. }
  30. if(formatPinyin!=null){
  31. return formatPinyin[0];//返回读音,如果多音字自返回一个
  32. }else{
  33. return String.valueOf(word);//非汉字则返回字符本身
  34. }
  35. }

测试调用上边写好的getEasyPinyins方法:

[java] view plain copy
  1. String statence="我24岁,java重生,长大!";//定义一个长字符串
  2. ntln("句子拼音组合的一种情况:"+Pinyin4jTest.getEasyPinyins(statence));//输出这段文字拼音的一种情况

这是大家利用pin4j把含有多音字、字母数字转成拼音的“唯一”或者常见的方法了,其运行结果如下:

[java] view plain copy
  1. 句子拼音组合的一种情况:wo24sui,javazhongsheng,zhangda!

利用递归获取中文句子的拼音组合的所有情况返回List形式

其实遇到多层循环嵌套或者一个2维数组每行取一个元素组合起来的所有组合情况,往往的解决思路就是递归了,pin4j把汉字转成拼音是返回的一个一维数组,如果是多音字这个一维数组里就有多个元素,如果不是多音字就一个元素,而含有多音字的中文句子就是从每个汉字对应的拼音数组取分别取一个组合起来的所有组合情况,进而用递推可以完美解决这个问题,如下,先定义如下几个方法:

[java] view plain copy
  1. /**
  2. * 获取一段文字的所有拼音组合情况,以list<String>形式返回
  3. */
  4. public static List<String> getHardPinyins(String s){
  5. if(s==null){
  6. s="";//null时处理,后边处理时报错
  7. }
  8. String[][] allPinyins=new String[s.length()][];//存放整个字符串的各个字符所有可能的拼音情况,如果非汉字则是它本身
  9. char[] words=s.toCharArray();//把这段文字转成字符数组
  10. for(int i=0;i<words.length;i++){
  11. allPinyins[i]=Pinyin4jTest.getAllPinyins(words[i]);//每个字符的所有拼音情况
  12. }
  13. String[] resultArray=Pinyin4jTest.recursionArrays(allPinyins,allPinyins.length,0);//用递归,求出这个2维数组每行取一个数据组合起来的所有情况
  14. return Arrays.asList(resultArray);//返回数组支持的固定大小的list(asList注意事项详见我的其他博客,可new LinkedList<String>(Arrays.asList()))来实现对结果随意操作
  15. }
  16. /**
  17. * 获取包含一个字符的拼音(多音字则以数组形式返回多个),非汉字则返回字符本身
  18. */
  19. public static String[] getAllPinyins(char word){
  20. HanyuPinyinOutputFormat pinyinFormat = new HanyuPinyinOutputFormat();   //创建拼音输入格式类
  21. pinyinFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);//指定格式中的大小写属性为小写
  22. pinyinFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);//指定音标格式无音标
  23. pinyinFormat.setVCharType(HanyuPinyinVCharType.WITH_V);//指定用v表示ü
  24. String[] formatPinyin=null;
  25. try {
  26. formatPinyin = PinyinHelper.toHanyuPinyinStringArray(word, pinyinFormat);//获取对应的汉字拼音,不是汉字返回null
  27. } catch (BadHanyuPinyinOutputFormatCombination e) {//会抛出异常,捕获异常
  28. //logger.error(e.getMessage());
  29. e.printStackTrace();
  30. }
  31. if(formatPinyin==null){
  32. formatPinyin=new String[1];
  33. formatPinyin[0]=String.valueOf(word);//返回读音,如果多音字自返回一个
  34. }
  35. return formatPinyin;
  36. }
  37. /**
  38. * 用递归方法,求出这个二维数组每行取一个数据组合起来的所有情况,返回一个字符串数组
  39. * @param s 求组合数的2维数组
  40. * @param len 此二维数组的长度,省去每一次递归长度计算的时间和空间消耗,提高效率
  41. * @param cursor 类似JDBC、数据库、迭代器里的游标,指明当前从第几行开始计算求组合数,此处从0开始(数组第一行)
  42. *                 避免在递归中不断复制剩余数组作为新参数,提高时间和空间的效率
  43. * @return String[] 以数组形式返回所有的组合情况
  44. */
  45. public static String[] recursionArrays(String[][] s,int len,int cursor){
  46. if(cursor<=len-2){//递归条件,直至计算到还剩2行
  47. int len1 = s[cursor].length;
  48. int len2 = s[cursor+1].length;
  49. int newLen = len1*len2;//上下2行的总共的组合情况
  50. String[] temp = new String[newLen];//存上下2行中所有的组合情况
  51. int index = 0;
  52. for(int i=0;i<len1;i++){//嵌套循环遍历,求出上下2行中,分别取一个数据组合起来的所有情况
  53. for(int j=0;j<len2;j++){
  54. temp[index] = s[cursor][i] + s[cursor+1][j];
  55. index ++;
  56. }
  57. }
  58. s[cursor+1]=temp;//把当前计算到此行的所有组合结果放在cursor+1行
  59. cursor++;//游标指向下一行,即上边的数据结果
  60. return Pinyin4jTest.recursionArrays(s,len,cursor);
  61. }else{
  62. return s[len-1];//返回最终的所有组合结果
  63. }
  64. }

其中Arrays.asList()的用法一定注意的事项或者陷阱,详见我的博文:Array.asList:数组转list时你一定要知道的“陷阱”!

代码上几乎每行都有注释,大家一看便明白了,下边测试上边写好的方法,如下:

[java] view plain copy
  1. String statence="我24岁,java重生,长大!";//定义一个长字符串
[java] view plain copy
  1. System.out.println("句子拼音组合所有情况如下:");
  2. List<String> list=Pinyin4jTest.getHardPinyins(statence);
  3. for(String ca:list){
  4. System.out.println(ca);
  5. }

运行结果如下:

[java] view plain copy
  1. 句子拼音组合所有情况如下:
  2. wo24sui,javazhongsheng,zhangda!
  3. wo24sui,javazhongsheng,zhangdai!
  4. wo24sui,javazhongsheng,changda!
  5. wo24sui,javazhongsheng,changdai!
  6. wo24sui,javachongsheng,zhangda!
  7. wo24sui,javachongsheng,zhangdai!
  8. wo24sui,javachongsheng,changda!
  9. wo24sui,javachongsheng,changdai!

一切都解决了,over!

pinyin4j把中文句子(含有多音字字母)转成拼音(二维数组递归求所有组合情况返回list)算法实现!相关推荐

  1. pinyin4j把中文句子(含有多音字字母)转成拼音(二维数组递归求所有组合情况返回list)算法实现!...

    介绍 Pinyin4j是一个流行的Java库,支持中文字符和拼音之间的转换.拼音输出格式可以定制,然而真正的把含有多音字.数字.字母的中文句子转成拼音得到所有的组合情况却有很大难度,我看过很多有关博客 ...

  2. php查找判断二维数组中是否含有某个值

    php判断二维数组中是否含有某个值 $arr = array(array('a', 'b'),array('c', 'd') );in_array('a', $arr); // 此时返回的永远都是 f ...

  3. 【240】python 一个二维数组和一个整数,判断数组中是否含有该整数

    ♣ 题目部分(原文见公众号:python宝) python宝: https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzU5Nj ...

  4. 如何批量制作字母加流水号的二维码

    我们以前的文章介绍过很多有关批量制作流水号条形码的方法,而且还可以根据自己的需要在流水号前面添加字母.日期等信息.其实同样的方法也可以批量生成二维码,例如数据AB0001.AB0002.AB0003. ...

  5. java 中文替换_java字符串汉字替换成拼音

    String str ="jhuywy48r在74yhf47tf6中7dgc782有3y..."; 后面还有几百个汉字 汉字的个数不确定 我想把里面所有的 汉字 换成对应的 拼音 ...

  6. PHP二维数组按照中文姓名首字母排序

    方法一: 直接排序不返回首字母 $old_list = $this->model->field('id, number, username, mobile')->where('xxx ...

  7. php 二维数组字母排序,PHP二维数组获取第一个中文首字母并排序 筋斗云网络

    array(29) { [0]=> array(4) { ["areaid"]=> string(1) "0" ["areaname&qu ...

  8. 二维数组与字符数组——英文字母、数字字符及其他字符的个数

    [问题描述] 编写程序,输入字符串,统计英文字母.数字字符及其他字符的个数. [输入形式] 一个字符串 [输出形式] 三个数,之间用空格隔开 [样例输入] abc129++*ABC [样例输出] 6 ...

  9. 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

    题目解析部分 题目中说的这个数组使我们所熟知的杨氏矩阵 拿到一道题的解题思路应该是这样的:先看这道题中所用到的知识点,然后选用合适的类型和返回类型.先用伪代码来将整体思路屡清楚,再用代码去代替 伪代码 ...

最新文章

  1. 事件控制块的清空与状态查询
  2. [HNOI2008]GT考试
  3. 打开mobilenet——ssd的demo.py显示这样的错误解决方法:Intel MKL FATAL ERROR: Cannot load libmkl_avx.so or libmkl_def.s
  4. reids mysql 面试_月薪3k的后端面试点-Mysql和Redis
  5. Java基础(五):数组和Java方法
  6. Python-Spyder中文包正式发布!
  7. vesamenu.c32:not a COM32R image报错解决方案
  8. TF-IDF算法介绍及实现
  9. html5 m3u8 直播,html5 让video支持m3u8播放
  10. 【MVO MTSP】基于matlab灰狼算法求解多旅行商问题(同始终点)【含Matlab源码 1564期】
  11. 聊聊旷厂黑科技 | 更真切感受影像世界的美好,旷视实时双超AI算法还原你的“夏日回忆”...
  12. 大学毕业生推荐表的计算机水平,大学毕业生就业推荐表学校鉴定评语
  13. 如何给视频配上字幕?教你几种视频配字幕小妙招
  14. 使用Charles做弱网测试入门篇
  15. 金羚纸业化工厂人员定位解决方案,苏州新导助力化工厂人员定位系统实施
  16. android游戏手柄,没手柄也不怕 键盘玩Android游戏攻略
  17. vuetifyjs简介及其使用
  18. 推箱子android课程设计,推箱子游戏课程设计精选.doc
  19. 39. 腾讯面试题:有一千万条短信,有重复,以文本文件的形式保存,一行一条,有重复。
  20. Docker CE 还是 Docker EE

热门文章

  1. 生物医药实验室安全知识202203第二次作业
  2. 面试运维是否能接受加班 这样回答
  3. ActionBar取消底部分隔线效果
  4. PPT里被插入的视频如何倍速播放?
  5. Java项目:智能小区物业管理系统(java+JSP+bootstrap+JavaScript+servlet+Mysql)
  6. 如何将图片转化为表格?分享一个转换的方法
  7. Google 音乐的体验
  8. 使用腾讯企业邮箱调用SpringMail或者JavaMail发送邮件的发送服务器设置
  9. 河海大学2015年c语言考试答案,河海大学2010C语言清考试题.doc
  10. 15行python代码轻松批量下载()视频~