zoukankan      html  css  js  c++  java
  • 汉字转拼音问题

    这是一个非常经典的问题,同时,也是一个很难解决的问题。经典是因为,这个问题非常常见,而且有很多解决方案。

    难以解决是因为,存在多音字。可以发现很多股票软件都有这问题,比如zgyh 出来的不是中国银行,而是找不到,

    这是因为,中国银行的 “行” 查出来读的是 "xing" 。我篇文章我只是提供了一个原始的转换方法,就是查表。

    和你以前看过的算法可能不一样的是,我加了一个二分查找,我看到的一个开源的解决方案是顺序查找的。

        关于,多音字问题,我只有一个小规模的多音字表,从所有股票名称里面纠正过来的。解决方案是这样的:在查找拼音的时候,

    查找一下这个字是否在多音字表里面,如果是,那么查找前后组成的词,来决定读什么。如果有谁有完整的多音字表,或者有更好的

    解决方案,请给我留言。我一定拜谢。

    代码
    <?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 -1break;
            
    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);
    ?>

     <?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 -1break;
            
    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);
    ?>

    拼音表如下:-20319
    ai 
    -20317
    an 
    -20304
    ang 
    -20295
    ao 
    -20292
    ba 
    -20283
    bai 
    -20265
    ban 
    -20257
    bang 
    -20242
    bao 
    -20230
    bei 
    -20051
    ben 
    -20036
    beng 
    -20032
    bi 
    -20026
    bian 
    -20002
    biao 
    -19990
    bie 
    -19986
    bin 
    -19982
    bing 
    -19976
    bo 
    -19805
    bu 
    -19784
    ca 
    -19775
    cai 
    -19774
    can 
    -19763
    cang 
    -19756
    cao 
    -19751
    ce 
    -19746
    ceng 
    -19741
    cha 
    -19739
    chai 
    -19728
    chan 
    -19725
    chang 
    -19715
    chao 
    -19540
    che 
    -19531
    chen 
    -19525
    cheng 
    -19515
    chi 
    -19500
    chong 
    -19484
    chou 
    -19479
    chu 
    -19467
    chuai 
    -19289
    chuan 
    -19288
    chuang 
    -19281
    chui 
    -19275
    chun 
    -19270
    chuo 
    -19263
    ci 
    -19261
    cong 
    -19249
    cou 
    -19243
    cu 
    -19242
    cuan 
    -19238
    cui 
    -19235
    cun 
    -19227
    cuo 
    -19224
    da 
    -19218
    dai 
    -19212
    dan 
    -19038
    dang 
    -19023
    dao 
    -19018
    de 
    -19006
    deng 
    -19003
    di 
    -18996
    dian 
    -18977
    diao 
    -18961
    die -18952
    ding 
    -18783
    diu 
    -18774
    dong 
    -18773
    dou 
    -18763
    du 
    -18756
    duan 
    -18741
    dui 
    -18735
    dun 
    -18731
    duo 
    -18722
    -18710
    en 
    -18697
    er 
    -18696
    fa 
    -18526
    fan 
    -18518
    fang 
    -18501
    fei 
    -18490
    fen 
    -18478
    feng 
    -18463
    fo 
    -18448
    fou 
    -18447
    fu 
    -18446
    ga 
    -18239
    gai 
    -18237
    gan 
    -18231
    gang 
    -18220
    gao 
    -18211
    ge 
    -18201
    gei 
    -18184
    gen 
    -18183
    geng 
    -18181
    gong 
    -18012
    gou 
    -17997
    gu 
    -17988
    gua 
    -17970
    guai 
    -17964
    guan 
    -17961
    guang 
    -17950
    gui 
    -17947
    gun 
    -17931
    guo 
    -17928
    ha 
    -17922
    hai 
    -17759
    han 
    -17752
    hang 
    -17733
    hao 
    -17730
    he 
    -17721
    hei 
    -17703
    hen 
    -17701
    heng 
    -17697
    hong 
    -17692
    hou 
    -17683
    hu 
    -17676
    hua 
    -17496
    huai 
    -17487
    huan 
    -17482
    huang 
    -17468
    hui 
    -17454
    hun 
    -17433
    huo 
    -17427
    ji 
    -17417
    jia 
    -17202
    jian 
    -17185
    jiang 
    -16983
    jiao 
    -16970
    jie 
    -16942
    jin 
    -16915
    jing 
    -16733
    jiong 
    -16708
    jiu 
    -16706
    ju 
    -16689
    juan 
    -16664
    jue 
    -16657
    jun 
    -16647
    ka 
    -16474
    kai 
    -16470
    kan 
    -16465
    kang 
    -16459
    kao 
    -16452
    ke 
    -16448
    ken 
    -16433
    keng 
    -16429
    kong 
    -16427
    kou 
    -16423
    ku 
    -16419
    kua 
    -16412
    kuai 
    -16407
    kuan 
    -16403
    kuang 
    -16401
    kui 
    -16393
    kun 
    -16220
    kuo 
    -16216
    la 
    -16212
    lai 
    -16205
    lan 
    -16202
    lang 
    -16187
    lao 
    -16180
    le 
    -16171
    lei 
    -16169
    leng 
    -16158
    li 
    -16155
    lia 
    -15959
    lian 
    -15958
    liang 
    -15944
    liao 
    -15933
    lie 
    -15920
    lin 
    -15915
    ling 
    -15903
    liu 
    -15889
    long 
    -15878
    lou 
    -15707
    lu 
    -15701
    lv 
    -15681
    luan 
    -15667
    lue 
    -15661
    lun 
    -15659
    luo 
    -15652
    ma 
    -15640
    mai 
    -15631
    man 
    -15625
    mang 
    -15454
    mao 
    -15448
    me 
    -15436
    mei 
    -15435
    men 
    -15419
    meng 
    -15416
    mi 
    -15408
    mian 
    -15394
    miao 
    -15385
    mie 
    -15377
    min -15375
    ming 
    -15369
    miu 
    -15363
    mo 
    -15362
    mou 
    -15183
    mu 
    -15180
    na 
    -15165
    nai 
    -15158
    nan 
    -15153
    nang 
    -15150
    nao 
    -15149
    ne 
    -15144
    nei 
    -15143
    nen 
    -15141
    neng 
    -15140
    ni 
    -15139
    nian 
    -15128
    niang 
    -15121
    niao 
    -15119
    nie 
    -15117
    nin 
    -15110
    ning 
    -15109
    niu 
    -14941
    nong 
    -14937
    nu 
    -14933
    nv 
    -14930
    nuan 
    -14929
    nue 
    -14928
    nuo 
    -14926
    -14922
    ou 
    -14921
    pa 
    -14914
    pai 
    -14908
    pan 
    -14902
    pang 
    -14894
    pao 
    -14889
    pei 
    -14882
    pen 
    -14873
    peng 
    -14871
    pi -14857
    pian 
    -14678
    piao 
    -14674
    pie 
    -14670
    pin 
    -14668
    ping 
    -14663
    po 
    -14654
    pu 
    -14645
    qi 
    -14630
    qia 
    -14594
    qian 
    -14429
    qiang 
    -14407
    qiao 
    -14399
    qie 
    -14384
    qin 
    -14379
    qing 
    -14368
    qiong 
    -14355
    qiu 
    -14353
    qu 
    -14345
    quan 
    -14170
    que 
    -14159
    qun 
    -14151
    ran 
    -14149
    rang 
    -14145
    rao 
    -14140
    re 
    -14137
    ren 
    -14135
    reng 
    -14125
    ri 
    -14123
    rong 
    -14122
    rou 
    -14112
    ru 
    -14109
    ruan 
    -14099
    rui 
    -14097
    run 
    -14094
    ruo 
    -14092
    sa 
    -14090
    sai 
    -14087
    san 
    -14083
    sang 
    -13917
    sao 
    -13914
    se 
    -13910
    sen 
    -13907
    seng 
    -13906
    sha 
    -13905
    shai 
    -13896
    shan 
    -13894
    shang 
    -13878
    shao 
    -13870
    she 
    -13859
    shen 
    -13847
    sheng 
    -13831
    shi 
    -13658
    shou 
    -13611
    shu 
    -13601
    shua 
    -13406
    shuai 
    -13404
    shuan 
    -13400
    shuang 
    -13398
    shui 
    -13395
    shun 
    -13391
    shuo 
    -13387
    si 
    -13383
    song 
    -13367
    sou 
    -13359
    su 
    -13356
    suan 
    -13343
    sui 
    -13340
    sun 
    -13329
    suo 
    -13326
    ta 
    -13318
    tai 
    -13147
    tan -13138
    tang 
    -13120
    tao 
    -13107
    te 
    -13096
    teng 
    -13095
    ti 
    -13091
    tian 
    -13076
    tiao 
    -13068
    tie 
    -13063
    ting 
    -13060
    tong 
    -12888
    tou 
    -12875
    tu 
    -12871
    tuan 
    -12860
    tui 
    -12858
    tun 
    -12852
    tuo 
    -12849
    wa 
    -12838
    wai 
    -12831
    wan 
    -12829
    wang 
    -12812
    wei 
    -12802
    wen 
    -12607
    weng 
    -12597
    wo 
    -12594
    wu 
    -12585
    xi 
    -12556
    xia 
    -12359
    xian 
    -12346
    xiang 
    -12320
    xiao 
    -12300
    xie 
    -12120
    xin 
    -12099
    xing 
    -12089
    xiong 
    -12074
    xiu 
    -12067
    xu 
    -12058
    xuan 
    -12039
    xue 
    -11867
    xun 
    -11861
    ya 
    -11847
    yan 
    -11831
    yang 
    -11798
    yao 
    -11781
    ye 
    -11604
    yi 
    -11589
    yin 
    -11536
    ying 
    -11358
    yo 
    -11340
    yong 
    -11339
    you 
    -11324
    yu 
    -11303
    yuan 
    -11097
    yue 
    -11077
    yun 
    -11067
    za 
    -11055
    zai 
    -11052
    zan 
    -11045
    zang 
    -11041
    zao 
    -11038
    ze 
    -11024
    zei 
    -11020
    zen 
    -11019
    zeng 
    -11018
    zha 
    -11014
    zhai 
    -10838
    zhan 
    -10832
    zhang 
    -10815
    zhao 
    -10800
    zhe 
    -10790
    zhen 
    -10780
    zheng 
    -10764
    zhi 
    -10587
    zhong 
    -10544
    zhou 
    -10533
    zhu 
    -10519
    zhua 
    -10331
    zhuai 
    -10329
    zhuan 
    -10328
    zhuang 
    -10322
    zhui 
    -10315
    zhun 
    -10309
    zhuo 
    -10307
    zi 
    -10296
    zong 
    -10281
    zou 
    -10274
    zu 
    -10270
    zuan 
    -10262
    zui 
    -10260
    zun 
    -10256
    zuo 
    -10254

  • 相关阅读:
    Largest Rectangle in Histogram, 求矩形图中最大的长方形面积
    MergeSortedArray,合并两个有序的数组
    Remove Duplicates from Sorted List ,除去链表中相邻的重复元素
    Word Search, 在矩阵中寻找字符串,回溯算法
    SubSets,SubSets2, 求数组所有子集
    Longest Substring Without Repeating Characters,求没有重复字符的最长字串
    Minimum Window Substring, 包含子串的最小窗口,双指针
    Sort Colors,颜色排序
    Search a 2D Matrix,在有序矩阵查找,二分查找的变形; 行有序,列有序查找。
    EditDistance,求两个字符串最小编辑距离,动态规划
  • 原文地址:https://www.cnblogs.com/wangjiangze/p/1962177.html
Copyright © 2011-2022 走看看