`

拼音语法检查

阅读更多

本程序是把输入的字符串转化为以空格间隔的拼音串,

如输入“zhongguoren",则会输出“zhong guo ren".

 

另外程序也利用了Pinyin4j.jar的包,处理开始时先把中文汉字转化为拼音(但对多音字支持不好,如:银行-->yin xing),先不管这个问题。

 

说白本程序就是把输入的英文字符串,按照拼音规则分割,不过其中也遇到一些问题,现在记录下来。其实网上我也找过,不过就是没实现出来。

 

第一种做法:把拼音字典从a ai an ang一直往下读入内存(其实共407个拼音而已),对字符串,从长度为1开始至字符串末尾,不断截取,在拼音字典内二分查找,

若存在,则连接下个字符,继续在拼音字典内二分查找;

若不存在,则证明这是拼音的最大匹配了,就作为结果保存;

直到字符串结束。

(测试多次后发现有bug,bug 1: deng,xiong这类拼音不能识别,加了判断ng结尾(已修正);

bug 2: 对tian这个拼音识别成: ti  an两个拼音。

本人觉得如果再加判断就会显得很难看。所以放弃这种做法。

 

其中pinyinDict的数据结构是String[]. DictOper.readDict()方法是读文件,并把每一行转化String,最终返回String数组。

拼音字典文件格式如下:

a
ai
an
ang
ao
ba
bai

...

 

 

代码如下:

	/**
	 * 通过拼音字典,二分查找是否存在拼音<br/>
	 * 贪婪算法,最大匹配拼音序列, bug: tiantian会分成ti an ti an
	 * 
	 * @param inputChar
	 * @return
	 * @author chow 2010-8-25 上午10:58:22
	 */
	@Deprecated
	public String _processString(char[] inputChar) {
		String temp = new String(inputChar);
		String[] strArray = temp.split(" ");
		StringBuffer result = new StringBuffer();
		if (pinyinDict == null || pinyinDict.length <= 0) {
			pinyinDict = DictOper.readPYDict();
		}
		for (int i = 0; i < strArray.length; i++) {
			String curStr = strArray[i];
			int curStrLen = curStr.length();
			boolean existWord = false;
			for (int beginIndex = 0, endIndex = 1; endIndex <= curStrLen; endIndex++) {
				String tmpKey = curStr.substring(beginIndex, endIndex);
				int index = Arrays.binarySearch(pinyinDict, tmpKey);
				// int gap = endIndex - beginIndex;
				if (index >= 0) { // 存在,则继续找下个字符
					if (endIndex == curStrLen) {
						result.append(tmpKey + " ");
					} else if (endIndex + 2 <= curStrLen
							&& curStr.substring(endIndex, endIndex + 2).equals(
									"ng")) {
						// 若后面两个字母是ng,则接上去
						result.append(curStr
								.substring(beginIndex, endIndex + 2)
								+ " ");
						beginIndex = endIndex + 2;
						endIndex = beginIndex;
						existWord = false;
						continue;
					}
					existWord = true;
					continue;
				}
				// 不存在且前面一个字符是存在的
				else if (existWord) {
					result.append(curStr.substring(beginIndex, --endIndex));
					result.append(" ");
					beginIndex = endIndex;
					existWord = false;
					continue;
				}
			}
		}
		// System.out.println("result:" + result.toString());
		return result.toString();
	}
 

 

 

第二种做法:

改变拼音字典的数据结构,采用Map<String, List>的格式,如下:

a:[a, ai, an, ang, ao]

b:[ba, bai, ban, bang, bao, bei, ben, beng, bi, bian, biao, bie, bin, bing, bo, bu]

...

 

程序的思想是:从字符串的第一个字符开始,若字符在字典里存在,则取出其对应的拼音串,并从该字符往后截取1个至5个字符,

(如:输入tianxia,第一个字符为't',则取出t:[ta, tai, tan, tang, tao, te, tei, teng, ti, tian, tiao, tie, ting, tong, tou, tu, tuan, tui, tun, tuo],

并截取t, ti, tia, tian, tianx, tianxi 六组字符串,取出最长一个匹配串[tian],将结果保存,从'tian'的'n'后一个字符开始循环,直至到字符串结束。

 

	/**
	 * 根据Map查找是否存在对应的拼音<br/>
	 * 贪婪算法,最大匹配拼音序列
	 * 
	 * @param inputChar
	 * @return 以空格间隔的拼音字符串,eg: zhong guo ren
	 * @author chow 2010-8-25 上午11:00:07
	 */
	public String _processStringByMap(char[] inputChar) {
		String temp = new String(inputChar);
		temp = PinyinHelper.toHanyuPinyinString(temp, outputFormat, "");
		String[] strArray = temp.split(" ");
		StringBuffer result = new StringBuffer();
		if (pyData == null) {
			pyData = DictOper.getPYData();
		}
		for (int i = 0; i < strArray.length; i++) {
			String curStr = strArray[i];
			int curStrLen = curStr.length();
			int beginIndex = 0, nextWordIndex = 0;
			while (beginIndex < curStrLen) {
				String firstLetter = curStr.substring(beginIndex,
						beginIndex + 1);
				List<String> list = pyData.get(firstLetter);
				if (list == null) {
					beginIndex += 1;
					nextWordIndex = beginIndex;
					continue;
				}
				for (int subLen = 1; subLen <= 6; subLen++) {
					if (beginIndex + subLen > curStrLen) {
						break;
					}
					String piece = curStr.substring(beginIndex, beginIndex
							+ subLen);
					if (list.contains(piece)) {
						nextWordIndex = subLen + beginIndex;
					}
				}
				// 若不存在任何匹配,begin和next都向后移一位
				if (nextWordIndex == beginIndex) {
					beginIndex += 1;
					nextWordIndex = beginIndex;
					continue;
				}
				String subStr = curStr.substring(beginIndex, nextWordIndex);
				result.append(subStr + " ");
				beginIndex = nextWordIndex;
			}
		}
		if (result.length() == 0) {
			result.append(temp);
		}
		return result.toString();
	}

 

做法二可以很好识别拼音串,但回头想想,其实程序还可以优化。

因为每个拼音字母可以组成的拼音的长度范围是可预见的。就是说以't'开头的拼音最短为长度为2(eg: ta),最长为4(eg: tian);

这时只要改变拼音字典的数据结构就可以了,写个程序统计一下各个拼音最长和最短的长度,更改后的拼音字典为:

a:[a, ai, an, ang, ao]
min:1,max:3

b:[ba, bai, ban, bang, bao, bei, ben, beng, bi, bian, biao, bie, bin, bing, bo, bu]
min:2,max:4

对于min和max可以用Map<String,Integer[]> pyLenMap保存,

 

for (int subLen = 1; subLen <= 6; subLen++) {
					if (beginIndex + subLen > curStrLen) {
						break;
					}

 

对于上面的for循环内的1与6可换成pyLenMap的min和max。

这样程序循环的次数就能更少。

另外附上拼音字典。

分享到:
评论
4 楼 AllenZhang 2010-09-06  
算法和分词算法是完全一样的。。。。。。。事实上也就是分词
一样无法回避歧义。比如xian 和 xi an
3 楼 yangguo 2010-09-06  
怎么会是二分查找,应该是树结构才对。
2 楼 lovefeng01 2010-09-05  
确实不错,希望lz继续完善。
1 楼 flashj 2010-09-05  
不错,很实用的一个东西。

相关推荐

    短语汉语拼音数据集以及工具

    2. 拼音纠正:检查并纠正输入的拼音错误,提高输入准确性。 3. 语音识别:配合语音识别技术,将语音转化为文字,拼音数据可以作为中间桥梁。 4. 自然语言处理:在文本分析和理解中,拼音信息可以帮助进行词性标注、...

    易语言简易拼音输入法

    它采用直观的汉语语法,使得不懂英语的用户也能快速上手。在这款输入法中,易语言作为开发工具,提供了构建用户界面和处理输入法逻辑的基础框架。 2. **拼音输入法**:拼音输入法是根据汉字的拼音来输入汉字的系统...

    易语言源码QQ拼音输入法导入易语言源码.rar

    对于易语言来说,可能需要将C++或C#等语言的QQ拼音输入法源码翻译成易语言的代码,这需要对两种语言的语法、内存管理和调用约定有深入理解。 5. 深入解析:QQ拼音输入法的核心部分可能涉及到字符串处理、汉字编码、...

    易语言组拼音游戏

    1. 易语言:易语言是一种国产的、面向对象的编程语言,以简洁明了的中文语法著称,旨在降低编程入门的难度。在这款游戏中,易语言被用来编写游戏逻辑、用户界面和交互功能。易语言提供了丰富的库函数和组件,使得...

    小学一年级拼音学习方法拼音学习诀窍.doc

    2. **日常用语法**:在实际的语言环境中教授拼音,让孩子在学习an、en、in等韵母时,将其与日常生活词汇关联,增强记忆,提升口语表达能力。 3. **口诀法**:利用儿歌和口诀使拼音教学更有趣,如“圆圆脸蛋梳小辫,...

    小学一年级拼音学习方法,拼音学习诀窍.doc

    2. 日常用语法:在实际语言环境中教授拼音,让孩子在学习拼音的同时学习词汇和口语表达。例如,学习"an、en、in"时,可以将其与实际地点或动作联系起来,增加记忆的趣味性和实用性。 3. 口诀法:运用儿歌和口诀,...

    VBA示例之 求人不如自已动手 取得汉字拼音的第一个字母

    VB6.0则是VBA的前身,虽然现在已被更新的版本替代,但其基本语法和概念在VBA中仍然适用。 在Excel的VBA环境中,我们可以创建一个模块,并编写函数或子程序来实现所需功能。在这个例子中,我们的目标是获取汉字的首...

    易语言拼音排序

    在拼音排序中,这个函数可能用于检查字符串的长度,以确保所有字符串具有相同的处理方式,例如,如果需要忽略短于一定长度的字符串。 2. **取文本中间**:此函数用于从一个字符串中提取指定位置开始的一段子串。在...

    易语言源码组拼音游戏.rar

    例如,可能使用内置的“字符串比较”命令来检查用户输入的拼音是否与预设的正确答案相符。 此外,游戏的计分系统也是重要的组成部分。易语言提供了丰富的数学运算和变量操作,使得开发者可以轻松实现得分的增加和...

    拼音复习二.doc

    2. 音节:音节由声母和韵母组成,例如“xié”、“zi”、“bái”等,文档通过让孩子们在正确的音节后面打勾,来检查他们对音节的理解和识别能力。 3. 声母与韵母的组合:在第三部分中,文档展示了声母与韵母结合...

    拼音-汉字-四线三格-田字格-Word可输入打印版.doc

    同时,Word还提供了拼写和语法检查功能,有助于纠正错误并提高输入准确性。 总的来说,这份“拼音-汉字-四线三格-田字格-Word可输入打印版.doc”文档结合了现代科技与传统教学方法,为汉语学习者提供了一种高效、...

    易语言文本转拼音源码.7z

    易语言是一种专为中国人设计的编程语言,它以简体中文作为编程语言的基本语法,使得非计算机专业的用户也能轻松上手。"易语言文本转拼音源码.7z" 文件是一个压缩包,其中包含了使用易语言编写的源代码,用于实现将...

    C#实现汉字转拼音或转拼音首字母的方法

    在C#中,可以使用`char.IsLetter`方法检查一个字符是否为字母,然后利用字符的Unicode编码通过某种映射算法找到对应的拼音编码。在本例中,数组`pyValue`中的值可能是根据这个算法预先计算好的结果。例如,当我们拿...

    一二年级百词拼音竞赛练习题-附答案.doc

    文档标题和描述中提到的是一个针对一、二年级学生设计的汉字拼音练习题,旨在帮助孩子们巩固和提高汉语拼音...同时,这份资料也可以作为家长或教师辅助教学的工具,以检查孩子的拼音掌握情况,并提供即时的反馈和纠正。

    苏教版二年级上册语文看拼音写词语(田字格).doc

    4. 错误纠正:每个单元末尾都有“改错”部分,这是为了训练学生的自我检查能力,找出并修正错误的拼音或汉字。这有助于培养学生的细心和准确性。 5. 字形结构与书写规范:文档使用了田字格,有助于学生正确把握汉字...

    易语言输入汉字与拼音比较命令使用讲解

    下面是一个简单的示例,演示如何使用输入字比较命令来检查用户输入的拼音是否与预设的汉字拼音相同: ```e .逻辑型 拼音匹配 .字符串 用户拼音 = "nihao" .字符串 汉字拼音 = "nǐhǎo" 拼音匹配 = 输入字比较 ...

    段落格式的设置PPT课件.pptx

    本文主要探讨了如何设置段落格式,包括对齐方式、缩进、行间距、项目符号和编号、特殊格式以及拼写和语法检查。 段落对齐方式是文本布局的基础,常见的对齐方式有五种:左对齐、居中、右对齐、两端对齐和分散对齐。...

    小学一年级语文带拼音的阅读训练(全).doc

    8. 至23的部分,每一段都是一个独立的故事或情境,涉及的内容包括天气、人物对话、自然现象、物品描述等,训练孩子阅读理解、词汇积累、语法规则和表达技巧。 24至结尾的内容由于缺失,无法详细解读,但可以推测这...

    首拼音取项目-易语言

    1. 易语言的基础语法:包括变量声明、控制结构(如循环、条件判断)、函数调用等,这些都是实现首拼音转换的基础。 2. 字符串处理:涉及到对汉字字符的读取、分割、转换为拼音等操作。易语言提供了丰富的字符串处理...

    Word2021怎样学习日语.docx

    - **语法检查**:如果启用了日语语言包,Word还会提供语法检查功能,帮助纠正书写错误。 - **语音朗读**:虽然Word2021本身不直接支持语音朗读功能,但可以通过结合其他软件(如Microsoft Edge浏览器中的朗读功能)...

Global site tag (gtag.js) - Google Analytics