主题:  用拼音检索问题的探讨

蓝鲸

职务:版主
等级:5
金币:42.1
发贴:2614
#12004/10/7 3:08:24
以前这也发过类似的帖,斑竹也帖上了一个源程序。
最近我一直在想这个事,概括起来有几种方法

第一种:用拼音输入法转数据库。具体方法是用输入法生成器,逆向把拼音输入法IME文件生成文本文件,然后去掉词组后,生成数据库。本方法比较通用,据点是可能引起检索速度慢。一种中和的方法是,在数据库中增加拼音检索字段,在增加记录时,即生成拼音检索码。

编辑历史:[此帖最近一次被 蓝鲸 编辑过(编辑时间:2004-10-07 03:36:46)]

非常大鱼

蓝鲸

职务:版主
等级:5
金币:42.1
发贴:2614
#22004/10/7 3:11:42
第二种,在SQL数据库中生成一拼音检索函数,优点是速度快,可以查询到一些生僻字,SQL代码如下:
CREATE FUNCTION fGetPy(@STR VARCHAR(500)='')
returns VARCHAR(500)
AS
BEGIN
DECLARE @strlen INT,@RETURN VARCHAR(500),@ii INT
DECLARE @n INT,@c CHAR(1),@chn nchar(1)

SELECT @strlen=len(@STR),@RETURN='',@ii=0
SET @ii=0
WHILE @ii<@strlen
BEGIN
SELECT @ii=@ii+1,@n=63,@chn=SUBSTRING(@STR,@ii,1)
IF @chn>'z'
SELECT @n = @n +1
,@c = CASE chn WHEN @chn THEN CHAR(@n) ELSE @c END
FROM(
SELECT TOP 27 * FROM (
SELECT chn = '吖'
UNION ALL SELECT '八'
UNION ALL SELECT '嚓'
UNION ALL SELECT '咑'
UNION ALL SELECT '妸'
UNION ALL SELECT '发'
UNION ALL SELECT '旮'
UNION ALL SELECT '铪'
UNION ALL SELECT '丌' --because have no 'i'
UNION ALL SELECT '丌'
UNION ALL SELECT '咔'
UNION ALL SELECT '垃'
UNION ALL SELECT '嘸'
UNION ALL SELECT '拏'
UNION ALL SELECT '噢'
UNION ALL SELECT '妑'
UNION ALL SELECT '七'
UNION ALL SELECT '呥'
UNION ALL SELECT '仨'
UNION ALL SELECT '他'
UNION ALL SELECT '屲' --no 'u'
UNION ALL SELECT '屲' --no 'v'
UNION ALL SELECT '屲'
UNION ALL SELECT '夕'
UNION ALL SELECT '丫'
UNION ALL SELECT '帀'
UNION ALL SELECT @chn) AS a
ORDER BY chn COLLATE Chinese_PRC_CI_AS
) AS b
ELSE SET @c='a'
SET @RETURN=@RETURN+@c
END
RETURN(@RETURN)
END

go
--测试
SELECT dbo.fgetpy('王小丫')

这是在网上下载的


非常大鱼

蓝鲸

职务:版主
等级:5
金币:42.1
发贴:2614
#32004/10/7 3:13:21
还有一种是代码法,代码如下:
function getpychar(char)
tmp=65536+asc(char)
if(tmp>=45217 and tmp<=45252) then getpychar= "A"
if(tmp>=45253 and tmp<=45760) then getpychar= "B"
if(tmp>=47761 and tmp<=46317) then getpychar= "C"
if(tmp>=46318 and tmp<=46825) then getpychar= "D"
if(tmp>=46826 and tmp<=47009) then getpychar= "E"
if(tmp>=47010 and tmp<=47296) then getpychar= "F"
if(tmp>=47297 and tmp<=47613) then getpychar= "G"
if(tmp>=47614 and tmp<=48118) then getpychar= "H"
if(tmp>=48119 and tmp<=49061) then getpychar= "J"
if(tmp>=49062 and tmp<=49323) then getpychar= "K"
if(tmp>=49324 and tmp<=49895) then getpychar= "L"
if(tmp>=49896 and tmp<=50370) then getpychar= "M"
if(tmp>=50371 and tmp<=50613) then getpychar= "N"
if(tmp>=50614 and tmp<=50621) then getpychar= "O"
if(tmp>=50622 and tmp<=50905) then getpychar= "P"
if(tmp>=50906 and tmp<=51386) then getpychar= "Q"
if(tmp>=51387 and tmp<=51445) then getpychar= "R"
if(tmp>=51446 and tmp<=52217) then getpychar= "S"
if(tmp>=52218 and tmp<=52697) then getpychar= "T"
if(tmp>=52698 and tmp<=52979) then getpychar= "W"
if(tmp>=52980 and tmp<=53640) then getpychar= "X"
if(tmp>=53689 and tmp<=54480) then getpychar= "Y"
if(tmp>=54481 and tmp<=52289) then getpychar= "Z"
end function

function getpy(str)
for i=1 to len(str)
getpy=getpy&getpychar(mid(str,i,1))
next
end function

if Request.Form("Text") <> "" then
    Response.Write getpy(Request.Form("Text"))
    Response.Write asc(Request.Form("Text")) + 65536
end if


非常大鱼

蓝鲸

职务:版主
等级:5
金币:42.1
发贴:2614
#42004/10/7 3:32:07
用代码法,缺点是只能检索一些常用字,但如:唑、骓、枇等字就无能为力了。也就是说,它只能检索到65536+ASCII码值范围为45217~52289之间。

是否大于52289的值也可以用上述方法呢?我检测了一些65536+ASCII值:

A组: 吖57273 腌60391 锕61369 嫒59080 砹60865
B组: 茇56536 钯61145 鲅63185
C组: 骖59118 粲62675

G组: 戆60848 罡61112 橄59855

P组: 嫖59086 珀59370

我不敢再往下了,看来与上面的规律完全不一样,应该另有编码规则。看来用代码法做真正实用的程序还不行。

很想知道用什么方法最好,如果能知道一些编码规律的话,大家一起讨论。


非常大鱼

蓝鲸

职务:版主
等级:5
金币:42.1
发贴:2614
#52004/10/7 4:30:36
拼音检索还有一个问题,就是多音字,特别是名字拼音,如:解、朝等字。要做一专业的搜索还真不容易。


非常大鱼

panliu888

职务:普通成员
等级:1
金币:0.0
发贴:26
#62004/10/7 14:28:29

相关文件:点这儿打开



蓝鲸

职务:版主
等级:5
金币:42.1
发贴:2614
#72004/10/7 20:03:20
谢谢楼上的文件。
有两个文件,一个与这里的第二种完全一样,另一个罗列了3775个中文,但还是没有扩展字符,而且觉得这种方法不如第二种方法。

下午我转换了拼音输入法,用程序除去了词组,还有27909行的字,除去估计(当然可以用程序统计)三分之一的同音字,可能应该有18000个汉字。


非常大鱼