数据处理——⽚假名→平假名转换算法
数据处理——⽚假名→平假名转换算法
前⼏天完成了⼀个需求,需要编写算法实现将数据集中的所有包含⽚假名的数据全部转换成平假名。经过调查发现,在⽇语中的⽚假名包含全⾓⽚假名、全⾓⽚假名(⼩号)半⾓⽚假名、⽚假名读⾳扩展这些种类的⽚假名。需求要求在⼤量数据转换过程中不可以将其他数据丢失,例如其中包含的其他字符不需要转换,但是也不可以丢失。因此我考虑到算法应该有识别数字、英⽂字母、空格、平假名、⽚假名、以及⽇⽂中的繁体字等功能。这就要明确这些字符在数据集中所占的字节长度,在此之后考虑应该建⽴对照表的⽅法完成需求。因为在数据集中的字符串是以多字节⽅式存储,⽽在编译环境中是以单字节存储,所以如果将对照表直接初始化在编译环境中,会产⽣字节长度不同的冲突,⽆法实现对应转换需求。
基于此,我尝试过将数据集中的字符串转换成单字节,此处⽤到了READ_ConvStringToStringEx函数,有关这⽅⾯的知识⼤家可以查询MultiByteToWideChar函数与WideCharToMultiByte函数的实现原理,我就不赘述了。但是在这⾥⼜遇到了困难,就是当将其转换后便⽆法判断字符串中字符所占内存长度,因为该⽅法只对多字节字符串有效。⾄此,只能再次更改解决⽅案。
最后我想到了使⽤外部⽂件导⼊⽅式,当将对照表以外部⽂件的形式导⼊时,我就可以⾃⼰定义编码⽅
式,⽽在编译环境中由于没有调查清楚⽇⽂的编码⽅式,因此就没有实现将编译环境中的单字节字符串转化成多字节字符串的功能,基于此我的对照表建⽴与业务调查基本结束。接下来进⾏算法编写,其中数据集中与对照表中的编码⽅式均为UTF-8的编码⽅式,我们都知道,UTF-8的编码⽅式下字节表⽰是这样的:
1字节 0xxxxxxx
2字节 110xxxxx 10xxxxxx
3字节 1110xxxx 10xxxxxx 10xxxxxx
4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
其中所有⽚假名所占字节数均为3,因此我编写了识别算法,让获取到的数据进⼊循环后可以根据长度判定是需要转换还是直接截取。以下是根据字符串下标判断该元素所占内存长度⽅法。
if(0x00==(strInput.at(i)&0x80))//1字节
else if((strInput.at(i)&0x80&& strInput.at(i)&0x40&& strInput.at(i)&0x20)==0x00)//2字节html符号代码对照表
else if((strInput.at(i)&0x80)&&(strInput.at(i)&0x40)&&(strInput.at(i)&0x20)&&(strInput.at(i)&0x10)==0x00)//3字节
else if((strInput.at(i)&0x80)&&(strInput.at(i)&0x40)&&(strInput.at(i)&0x20)&&(strInput.at(i)&0x10)&&(strInput.at(i)&0x08)==0)//4字节
0x80 1000 0000
0x40 0100 0000
0x20 0010 0000
0x10 0001 0000
0x08 0000 1000
如果是长度为3字节,就会进⼊我编写的⼏个循环中,因为考虑到算法的性能,我将命中率⾼的循环语句放置的较为靠前,并且如果在命中后就不会继续再进⼊其他循环,以提⾼性能。因为数据集中存在
着同为三字节却并⾮是⽚假名的字符,因此要多加⼀个判定以便确保数据不会丢失。并且⼤家在编程时要注意每次在进⼊下次循环前要记得将i值向后偏移相应的长度,并且要判断i值与获取的字符串的长度关系,当两者相等时需要结束算法的最外层循环,否则会有中断。⾄此,算法完成,在测试时⼜遇到了很多问题,设置了很多断点调试,最后终于也都解决了,需求成功实现。源代码就不放了。。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论