本文和大家分享一下汉字转拼音问题。
以发现很多股票软件都有这问题,比如zgyh 出来的不是中国银行,而是找不到,
这是因为,中国银行的 “行” 查出来读的是 "xing" 。我篇文章我只是提供了一个原始的转换方法,就是查表。
和你以前看过的算法可能不一样的是,我加了一个二分查找,我看到的一个开源的解决方案是顺序查找的。
关于,多音字问题,我只有一个小规模的多音字表,从所有股票名称里面纠正过来的。解决方案是这样的:在查找拼音的时候,
查找一下这个字是否在多音字表里面,如果是,那么查找前后组成的词,来决定读什么。站长教学网 eduyo.com
<?php
/**
* 初始化
*
* @param string $file 拼音代码对应表
* @return array 把这个对应表映射成array的格式
*/
function pinyin_init($file)
{
$pinyin = file($file);
if (empty($pinyin)) {
throw new Exception("load pinyin table error.");
}
foreach ($pinyin as $k => $item)
{
$item = explode("\t", $item);
$item[0] = trim($item[0]);
$item[1] = (int)trim($item[1]);
$pinyin[$k] = $item;
}
$pinyin[] = array('', -10248); //最后一个拼音的妈是 -10247
return $pinyin;
}
/**
* 查找一个字符串中,中文字符部分的拼音
*
* @param array $pingyin
* @param string $str 字符串
* @param string $in_encode 字符串的编码
* @return array
*/
function pingyin_get($pingyin, $str, $in_encode = 'gb2312')
{
if (strtolower($in_encode) != 'gb2312') {
$str = iconv($in_encode, 'gb2312', $str);
if (!$str) {
throw new Exception('invalid input string.');
}
}
$pinyin_arr = array();
$len = strlen($str);
for ($i = 0; $i < $len; $i )
{
if ($i == $len -1) break;
if (($code = pinyin_getcode_($str[$i], $str[$i 1])) != false) {
$i ;
if (($py = pinyin_find_($pingyin, $code)) !== false) {
$pinyin_arr[substr($str, $i - 1 , 2)] = $py;
}
}
}
return $pinyin_arr;
}
/**
* 内部函数,通过拼音码查找汉字
*
* @param array $pingyin
* @param int $code
* @return string/false
*/
function pinyin_find_($pingyin, $code)
{
$start = 0;
$count = count($pingyin) - 1;
$end = $count;
if ($code < $pingyin[0][1] || $code >= $pingyin[$end][1]) { //no found.
return false;
}
while ($start <= $end)
{
$mid = (int)($start ($end - $start)/2);
if ($mid == $count) { //正常情况下,应该是永远都不会执行到这里,但是为了逻辑上清晰点,还是决定写上
return $pingyin[$mid - 1][0];
} else if ($code >= $pingyin[$mid][1] && $code < $pingyin[$mid 1][1]) {
return $pingyin[$mid][0];
} else if ($code >= $pingyin[$mid 1][1]) {
$start = $mid 1;
} else {
$end = $mid - 1;
}
}
return false;
}
/**
* 内部函数,通过汉字的第一个字节 和 第二个字节,得到查找的code
*
* @param char $ch1
* @param char $ch2
* @return int
*/
function pinyin_getcode_($ch1, $ch2)
{
$num1 = ord($ch1);
$num2 = ord($ch2);
if ($num1 > 159 && $num1 < 248) {
return $num1 * 256 $num2 - 65536;
}
return false;
}
/**
* 基本配置信息
*/
define("CURRENT_PATH", dirname(__FILE__));
$pingin_file = CURRENT_PATH . "/gb-pinyin.table";
$pinyin = pinyin_init($pingin_file);
$py = pingyin_get($pinyin, "中国银行", 'utf-8');
echo iconv('gb2312', 'utf-8', print_r($py, true));
echo implode("'", $py);
?>
(责任编辑:ken)