如何实现通过汉字的拼音或首拼快速检索(含部分源码)

      前段时间有难得的一周左右的时间空闲,在朋友的拉动下玩了开心网,里面有一个小功能很有意思,选择人名的时候,可以根据拼音 或 拼音首字母快速输入,这个功能如果用在我们的应用系统里,对软件的易用性非常有帮助,于是研究了一把,并把全部代码扩充到了E8.Net工作流架构里面。

      如图:

      如何实现通过汉字的拼音或首拼快速检索(含部分源码)如何实现通过汉字的拼音或首拼快速检索(含部分源码)

     输入拼音首字母或全拼均可以快速检索,这个功能对于很多软件系统中人名检索,知识库关键字等快速检索很有帮助。由于E8.Net工作流架构里本来就已经实现了类似google的快速检索的控件(有博客介绍),因此实现通过拼音检索就变得相对容易了。

    实现思路如下:

         需要检索的内容,数据库里保存汉字相应的拼音首字母和拼音。 (E8.Net中已经包含了将汉字转换为拼音及首拼的全部源码)

          汉字转换拼音部分代码如下:

            

public   class  GBToPY
    {
        
private   static   int [] FIRST_TABLE  =  {  45217 45253 45761 46318 46826 ,
                
47010 47297 47614 47614 48119 49062 49324 49896 50371 ,
                
50614 50622 50906 51387 51446 52218 52218 52218 52698 ,
                
52980 53689 54481 55289  };

        
private   static   string [] ALL_VALUE  =  {  " zuo " " zun " " zui " " zuan " " zu " ,
                
" zou " " zong " " zi " " zhuo " " zhun " " zhui " " zhuang " " zhuan " ,
                
" zhuai " " zhua " " zhu " 如何实现通过汉字的拼音或首拼快速检索(含部分源码)..};

        
private   static   int [] ALL_CODE  =  {  - 10254 - 10256 - 10260 - 10262 ,
                
- 10270 - 10274 - 10281 - 10296 - 10307 - 10309 - 10315 - 10322 ,
                
- 10328 - 10329 - 10331 - 10519 - 10533 - 10544 - 10587 - 10764 ,
                
- 10780 - 10790 - 10800 - 10815 - 10832 - 10838 - 11014 - 11018 ,
                
- 11019 - 11020 - 11024 - 11038 - 11041 - 11045 - 11052 - 11055 ,
                
- 11067 - 11077 - 11097 - 11303 - 11324 - 11339 - 11340 - 11358 ,
                
- 12607 - 12802 - 12812 - 12829 - 12831 - 12838 - 12849 - 12852 ,
                
- 12858 - 12860 - 12871 - 12875 - 12888 - 13060 - 13063 - 13068 ,
                
- 13076 - 13091 - 13095 - 13096 - 13107 - 13120 - 13138 - 13147 ,
                
- 13318 - 13326 - 13329 - 13340 - 13343 - 13356 - 13359 - 13367 ,
                
- 13383 - 13387 - 13391 - 13395 - 13398 - 13400 - 13404 - 13406 ,
                
- 13601 - 13611 - 13658 如何实现通过汉字的拼音或首拼快速检索(含部分源码).};

        
        
public   static   string  getAllPY( char  gb2312)
        {
            
int  ascii  =  getCnAscii(gb2312);
            
if  (ascii  ==   0 )
            { 
//  取ascii时出错
                 return   new   string (gb2312,  1 );
            }
            
else
            {
                
string  spell  =  getSpellByAscii(ascii);
                
if  (spell  ==   null )
                {
                    
return   new   string (gb2312,  1 );
                }
                
else
                {
                    
return  spell;
                } 
//  end of if spell == null
            }
        }

        
public   static   char  getFirstPY( char  ch)
        {
            
if  (ch  >=   0   &&  ch  <=   0x7F )
            {
                
return  ch;
            }
            
int  gb  =   0 ;

            
byte [] bytes  =  Encoding.GetEncoding( " gb2312 " ).GetBytes( new   string (ch,  1 ));
            
if  (bytes.Length  <   2 )
            {
                gb 
=  byte2Int(bytes[ 0 ]);
            }
            gb 
=  (bytes[ 0 <<   8   &   0xff00 +  (bytes[ 1 &   0xff );
            
if  (gb  <  FIRST_TABLE[ 0 ])
                
return  ch;
            
int  i;
            
for  (i  =   0 ; i  <   26 ++ i)
            {
                
if  (match(i, gb))
                    
break ;
            }
            
if  (i  >=   26 )
                
return  ch;
            
else
                
return  ( char )( 65   +  i);
        }

        
public   static   string  getFirstPY( string  src)
        {
            StringBuilder sb 
=   new  StringBuilder();
            
int  len  =  src.Length;
            
int  i;
            
for  (i  =   0 ; i  <  len; i ++ )
            {
                sb.Append(getFirstPY(src[i]));
            }
            
return  sb.ToString();
        }

        
private   static   int  getCnAscii( char  cn)
        {
            
byte [] bytes  =   null ;
            bytes 
=  Encoding.GetEncoding( " gb2312 " ).GetBytes( new   string (cn,  1 ));
            
if  (bytes  ==   null   ||  bytes.Length  >   2   ||  bytes.Length  <=   0 )
            {
                
return   0 ;
            }
            
if  (bytes.Length  ==   1 )
            {
                
return  bytes[ 0 ];
            }
            
else
            {
                
int  hightByte  =  bytes[ 0 ];
                
int  lowByte  =  bytes[ 1 ];
                
int  ascii  =  ( 256   *  hightByte  +  lowByte)  -   256   *   256 ;
                
return  ascii;
            }
        }

        
private   static   string  getSpellByAscii( int  ascii)
        {
            
if  (ascii  >   0   &&  ascii  <   160 )
            { 
//  单字符
                 return   new   string (( char )ascii,  1 );
            }
            
if  (ascii  <   - 20319   ||  ascii  >   - 10247 )
            { 
//  不知道的字符
                 return   null ;
            }
            
int  first  =   0 ;
            
int  sLast  =  ALL_CODE.Length  -   1 ;
            
int  last  =  ALL_CODE.Length  -   1 ;
            
int  mid;
            
int  temp;
            
while  ( true )
            {
                mid 
=  (first  +  last)  >>   1 ;
                
if  (ascii  ==  ALL_CODE[mid])
                {
                    
return  ALL_VALUE[mid];
                }
                
else   if  (ascii  >  ALL_CODE[mid])
                {
                    temp 
=  mid  -   1 ;
                    
if  (temp  >=   0 )
                    {
                        
if  (ascii  <  ALL_CODE[temp])
                        {
                            
return  ALL_VALUE[mid];
                        }
                        
else
                        {
                            last 
=  mid;
                        }
                    }
                    
else
                    {
                        
return  ALL_VALUE[ 0 ];
                    }
                }
                
else
                {
                    
if  (mid  +   1   <=  sLast)
                    {
                        first 
=  mid  +   1 ;
                    }
                    
else
                    {
                        
return  ALL_VALUE[sLast];
                    }
                }
            }
        }

        
private   static   bool  match( int  i,  int  gb)
        {
            
if  (gb  <  FIRST_TABLE[i])
            {
                
return   false ;
            }
            
int  j  =  i  +   1 ;
            
//  字母Z使用了两个标签
             while  (j  <   26   &&  (FIRST_TABLE[j]  ==  FIRST_TABLE[i]))
            {
                
++ j;
            }
            
if  (j  ==   26 )
                
return  gb  <=  FIRST_TABLE[j];
            
else
                
return  gb  <  FIRST_TABLE[j];
        }

        
private   static   int  byte2Int( byte  b)
        {
            
if  (b  <   0 )
            {
                
return   256   +  b;
            }
            
else
            {
                
return  b;
            }
        }

        
public   static   bool  isSpliter( char  c)
        {
            
char [] spliter  =  {  ' , ' ' ' ' ; ' ' '  };
            
foreach  ( char  cc  in  spliter)
            {
                
if  (c  ==  cc)
                {
                    
return   true ;
                }
            }
            
return   false ;
        }

        
public   static   string [] split( string  src)
        {
            
string  text  =  src.Trim();
            StringBuilder sb 
=   new  StringBuilder();
            ArrayList al 
=   new  ArrayList();
            
int  i  =   0 ;
            
// 跳过之前的分隔符
             for  (i  =   0 ; i  <  text.Length; i ++ )
            {
                
if  ( ! isSpliter(text[i]))
                {
                    
break ;
                }
            }
            
for  (; i  <  text.Length; i ++ )
            {
                
if  (isSpliter(text[i]))
                {
                    
if  (sb.Length  >   0 )
                    {
                        al.Add(sb.ToString());
                    }
                    sb 
=   new  StringBuilder();
                }
                
else
                {
                    sb.Append(text[i]);
                }
            }
            
if  (sb.Length  >   0 )
            {
                al.Add(sb.ToString());
            }
            
if  (al.Count  >   0 )
            {
                
string [] ret  =   new   string [al.Count];
                
for  (i  =   0 ; i  <  al.Count; i ++ )
                {
                    ret[i] 
=  ( string )al[i];
                }
                
return  ret;
            }
            
else
            {
                
return   null ;
            }
        }
    }

 

               

         通过异步方式即时获取检索内容(JAVASCRIPT脚本中实现缓存机制,保证性能)

             具体代码可以参考另一篇博客: http://www.cnblogs.com/cancanwyq/archive/2008/04/17/1158178.html

 

      这样基本上就很容易实现上面图例所示的功能了。

 

       E8.Net工作流平台为企业应用开发提供了一个起点,欢迎访问 :http://***/productFlow.htm

 

 

 

你可能感兴趣的:(源码)