我找到最全的数据是slowwind9999上传到csdn的unicode汉字编码表,包括全部20902个汉字的全拼、五笔、郑码、UNICODE、GBK、笔画数 部首,以及笔顺编号(拼音部分没有音调,而且个别注音有误,如 囍,猤,啹等字,使用需注意。)我提取了其中的笔顺数据,又用江志键的“实用汉字转拼音”程序制作了unicode汉字音调版,其中中文汉字用四声标注,319个日韩汉字没有音调以示区别,并根据汉典的数据略作修正(但仍可能存在错误)。有了这两个对照表,下面的工作就简单了。
# 建立拼音辞典
dic_py = dict()
f_py = open('py.txt','r')
content_py = f_py.read()
lines_py = content_py.split('\n')
n=len(lines_py)
for i in range(0,n-1):
word_py, mean_py = lines_py[i].split('\t', 1)
dic_py[word_py]=mean_py
f_py.close()
笔顺字典的处理方法也完全相同,虽然文本有两万行,导入还是很快的,0.5秒左右。如果把这两个文件合并起来统一处理,应该可以更快。
# 辞典查找函数
def searchdict(dic,uchar):
if isinstance(uchar, str):
uchar = unicode(uchar,'utf-8')
if uchar >= u'\u4e00' and uchar < = u'\u9fa5':
value=dic.get(uchar.encode('utf-8'))
if value == None:
value = '*'
else:
value = uchar
return value
查找中文,一律转为UTF8字符串,汉字外的其他字符不做处理,原样输出。如果需要声母,只输出拼音的第一个字符就是了。只要资料准确,比较起来就很轻松了。数字在字母之前,爱(ai4)便会比昂(ang2)靠前,而笔顺值的位数代表了笔画数,数值对应笔划权重,直接比较数字大小就可以得到正确的顺序。代码如下:
#比较单个字符
def comp_char_PY(A,B):
if A==B:
return -1
pyA=searchdict(dic_py,A)
pyB=searchdict(dic_py,B)
if pyA > pyB:
return 1
elif pyA < pyB:
return 0
else:
bhA=eval(searchdict(dic_bh,A))
bhB=eval(searchdict(dic_bh,B))
if bhA > bhB:
return 1
elif bhA < bhB:
return 0
else:
return 'Are you kidding?'
#比较字符串
def comp_char(A,B):
charA = A.decode('utf-8')
charB = B.decode('utf-8')
n=min(len(charA),len(charB))
i=0
while i < n:
dd=comp_char_PY(charA[i],charB[i])
if dd == -1:
i=i+1
if i==n:
dd=len(charA)>len(charB)
else:
break
return dd
# 排序函数
def cnsort(nline):
n = len(nline)
lines='\n'.join(nline)
for i in range(1, n): #插入法
tmp = nline[i]
j = i
while j > 0 and comp_char(nline[j-1],tmp):
nline[j] = nline[j-1]
j -= 1
nline[j] = tmp
return nline
现在我们就可以按照字典的规范给中文排序了。
char=['赵','钱','孙','李','佘']
char=cnsort(char)
for item in char:
print item.decode('utf-8').encode('gb2312')
终于得到了“李钱佘孙赵”,样例文件点此下载cnsort.zip。
这里我没有考虑多音字的情况。如果想让程序自动识别,可以增加多音词组对照表,通过上下文来判断。我不知道哪里有这样的数据,反正对于多音字不太多的情形,手动调整也就够了。