标题: [其他] 高效的纯批处理汉字转拼音 [打印本页]
作者: CrLf 时间: 2015-8-11 00:54 标题: 高效的纯批处理汉字转拼音
本帖最后由 CrLf 于 2015-8-11 20:02 编辑
因为使用简表直接比较大小,所以需要确保区域语言设置为按中文拼音排序,否则结果可能不正确:- @echo off
-
- setlocal enabledelayedexpansion
- call :py_初始化
-
- for /f "delims=" %%a in ('help') do (
- set input=%%a
- echo;%%a
- call :py input newstr
- echo !newstr!
- echo;
- )
-
- pause
- exit /b
-
- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
- :py_初始化 // 需启用变量延迟后调用
- set 字典长度=0
- for %%a in (
-
- /*简表包含405个拼音,已知囊括20855个汉字范围*/
-
- 吖a 哎ai 安an 肮ang 凹ao 八ba 挀bai 扳ban 邦bang 勹bao 萡be 陂bei 奔ben 伻beng 皀bi
- 边bian 标biao 憋bie 汃bin 仌bing 癶bo 卜bu 攃ca 猜cai 参can 仓cang 撡cao 刂ce 岑cen 噌ceng
- 叉cha 犲chai 觇chan 伥chang 抄chao 车che 抻chen 阷cheng 吃chi 冲chong 抽chou 出chu 欻chua 揣chuai 川chuan
- 刅chuang 吹chui 杶chun 逴chuo 呲ci 匆cong 凑cou 粗cu 汆cuan 崔cui 邨cun 搓cuo 咑da 呆dai 亻dan
- 当dang 刀dao 恴de 揼den 灯deng 仾di 嗲dia 敁dian 刁diao 爹die 丁ding 丟diu 东dong 吺dou 剢du
- 剬duan 垖dui 吨dun 多duo 妸e 诶ei 奀en 鞥eng 儿er 发fa 帆fan 匚fang 飞fei 分fen 丰feng
- 仏fo 紑fou 夫fu 旮ga 侅gai 甘gan 冈gang 皋gao 戈ge 给gei 根gen 刯geng 工gong 勾gou 估gu
- 瓜gua 乖guai 关guan 光guang 归gui 衮gun 呙guo 哈ha 还hai 佄han 夯hang 蒿hao 诃he 黒hei 拫hen
- 亨heng 叿hong 齁hou 乎hu 花hua 怀huai 欢huan 巟huang 灰hui 昏hun 吙huo 丌ji 加jia 戋jian 江jiang
- 艽jiao 阶jie 巾jin 仱jing 坰jiong 丩jiu 圧ju 姢juan 撅jue 军jun 咔ka 开kai 刊kan 闶kang 尻kao
- 苛ke 肎ken 劥keng 空kong 抠kou 扝ku 夸kua 蒯kuai 宽kuan 匡kuang 亏kui 坤kun 扩kuo 垃la 来lai
- 兰lan 啷lang 捞lao 仂le 雷lei 塄leng 唎li 嫾lian 簗liang 蹽liao 毟lie 拎lin 伶ling 溜liu 囖lo
- 龙long 瞜lou 撸lu 峦luan 掠lue 抡lun 啰luo 驴lv 略lve 妈ma 埋mai 颟man 牤mang 猫mao 孭me
- 沒mei 椚men 擝meng 咪mi 芇mian 喵miao 吀mie 民min 名ming 谬miu 摸mo 哞mou 呒mu 乸na 腉nai
- 囡nan 囔nang 孬nao 讷ne 馁nei 嫩nen 能neng 妮ni 拈nian 娘niang 鸟niao 捏nie 脌nin 宁ning 牛niu
- 农nong 羺nou 奴nu 奻nuan 挪nuo 女nv 噢o 讴ou 帊pa 拍pai 眅pan 乓pang 抛pao 呸pei 喷pen
- 匉peng 丕pi 囨pian 剽piao 氕pie 拼pin 乒ping 攴po 剖pou 扑pu 七qi 掐qia 扦qian 羌qiang 悄qiao
- 切qie 钦qin 青qing 卭qiong 丘qiu 区qu 奍quan 炔qv 夋qun 冄ran 穣rang 荛rao 惹re 人ren 扔reng
- 日ri 戎rong 禸rou 邚ru 撋ruan 甤rui 闰run 叒ruo 仨sa 毢sai 三san 桒sang 掻sao 色se 森sen
- 僧seng 杀sha 筛shai 山shan 伤shang 捎shao 奢she 申shen 升sheng 尸shi 収shou 殳shu 刷shua 衰shuai 闩shuan
- 双shuang 谁shui 吮shun 说shuo 厶si 忪song 凁sou 苏su 狻suan 夊sui 孙sun 莏suo 他ta 咍tai 坍tan
- 汤tang 仐tao 忑te 膯teng 剔ti 天tian 旫tiao 帖tie 厅ting 囲tong 偷tou 凸tu 猯tuan 推tui 吞tun
- 乇tuo 屲wa 歪wai 弯wan 尪wang 危wei 昷wen 翁weng 挝wo 乌wu 夕xi 虾xia 仙xian 乡xiang 灲xiao
- 些xie 心xin 星xing 凶xiong 休xiu 戌xu 吅xuan 削xv 坃xun 丫ya 咽yan 央yang 幺yao 耶ye 一yi
- 乚yin 応ying 哟yo 佣yong 优you 迂yu 囦yuan 曰yv 晕yun 帀za 灾zai 兂zan 赃zang 遭zao 则ze
- 贼zei 怎zen 増zeng 扎zha 夈zhai 枬zhan 弡zhang 钊zhao 蜇zhe 贞zhen 凧zheng 之zhi 中zhong 舟zhou 朱zhu
- 抓zhua 跩zhuai 专zhuan 妆zhuang 隹zhui 迍zhun 拙zhuo 孖zi 宗zong 邹zou 租zu 劗zuan 厜zui 尊zun 昨zuo
- ) do (
- set 字!字典长度!=%%a
- set /a 字典长度+=1
- )
-
- exit /b
-
- :py
- setlocal enabledelayedexpansion
- set "$=!%1!#"
- set N=&for %%a in (4096 2048 1024 512 256 128 64 32 16)do if !$:~%%a!. NEQ . set/aN+=%%a&set $=!$:~%%a!
- set $=!$!fedcba9876543210&set/aN+=0x!$:~16,1!
- rem 二分回溯法求字符串长度
-
- set/a length=N
-
- set "newstr="
-
- for /l %%a in (%length% -1 1) do (
- set char=!%1:~-%%a,1!
- set ret=!char!
- set m=0
-
- if !char! geq 吖 if !char! leq 咗 (
- for %%c in (256 128 64 32 16 8 4 2 1) do (
- set /a bak=m,m+=%%c
- for /l %%m in (!m! 999 %字典长度%) do (
- if !字%%m:~^,1! leq !char! (
- set bak=%%m
- set "ret= !字%%m:~1! "
- )
- )
- set m=!bak!
- )
- rem 二分法快速定位拼音
- )
-
- set newstr=!newstr!!ret!
- )
-
- for /f "delims=" %%a in ("!newstr!") do endlocal&set %2=%%a
- exit /b
复制代码
作者: CrLf 时间: 2015-8-11 01:02
顶楼代码改进自旧帖 http://www.bathome.net/viewthread.php?tid=14681,在算法上有大幅优化:
1、使用二分法快速定位在字典中的对应位置
2、使用二分回溯查表法计算字符串长度
3、将字典保存在伪数组中
4、利用特殊语法技巧化简流程
字典根据以下两贴的资料进行重新整理校对,更完整和准确:
http://www.bathome.net/viewthread.php?tid=36847
http://demon.tw/reverse/cmd-internal-if.html
作者: CrLf 时间: 2015-8-11 01:08
还有更快的算法吗?有木有人来挑战?仅限纯批
作者: aa77dd@163.com 时间: 2015-8-11 11:31
没运行你的代码, 但不知你是否充分考虑了边缘问题- (echo 阿& echo 啊& echo 呵& echo 吖) | sort
- (echo 做& echo 坐& echo 昨) | sort
- if 坐 lss 昨 echo oh
复制代码
作者: 523066680 时间: 2015-8-11 11:57
噢,想起上次有一个取拼音开头的Excel宏函数- Option Explicit
- Public Function LChin(Str As String) As Variant
- On Error Resume Next
- Str = StrConv(Str, vbNarrow)
- If Asc(Str) > 0 Or Err.Number = 1004 Then LChin = ""
- LChin = WorksheetFunction.VLookup(Str, [{"吖","a";"八","b";"嚓","c";"咑","d";"鵽","e";"发","f";"猤","g";"铪","h";"夻","j";"咔","k";"垃","l";"嘸","m";"旀","n";"噢","o";"妑","p";"七","q";"囕","r";"仨","s";"他","t";"屲","w";"夕","x";"丫","y";"帀","z"}], 2)
- End Function
复制代码
作者: CrLf 时间: 2015-8-11 15:01
回复 4# aa77dd@163.com
试了下没问题啊,简表的格式是 [区间起始汉字][对应拼音]
作者: aa77dd@163.com 时间: 2015-8-11 16:21
本帖最后由 aa77dd@163.com 于 2015-8-11 16:27 编辑
回复 6# CrLf - set input=坐下
- echo;%input%
- call :py input newstr
- echo !newstr!
- echo;
复制代码
得到的结果复制代码
如果 "昨" 是 zuo 音的第一个字, 你的代码会把排序在 "昨" 后面的汉字都忽略掉而不给出拼音的翻译结果, 这个边界必须有不同的处理代码- if !char! geq 吖 if !char! leq 昨
复制代码
应该改成- if !char! geq 吖 if !char! leq "zuo 音的最后一个汉字"
复制代码
作者: CrLf 时间: 2015-8-11 17:07
回复 7# aa77dd@163.com
噢,是的
我擦,顺手一改反倒给改错了
感谢指正!
作者: Demon 时间: 2015-8-11 18:25
mark
作者: CrLf 时间: 2015-8-11 19:51
回复 5# 523066680
嗯,通用性也受同样的限制
不过“鵽”对应 e 错了,这个字是 duo
作者: aa77dd@163.com 时间: 2015-8-11 20:12
本帖最后由 aa77dd@163.com 于 2015-8-11 20:13 编辑
因为想到可以用 sort | findstr 来找到索引数字, 所以就实现了一下
没考虑特殊字符, zuo 音的最后一个字符不知道是什么, 如果遇到排在 昨 后面但没有读音的字符(可能就不是汉字吧, 当然也不是英文字母之类的), 这里也会处理成 有拼音 zuo, 嘿嘿
至于效率速度这些东东, 更木有考虑了- @echo off
- setlocal enabledelayedexpansion
- call :init
-
- set "str=你好, 世界 hello world 昨坐安按阿吖拼音汉字"
- set "PY="
- for /l %%i in (0 1 28) do (
- set "chr=!str:~%%i,1!"
- if "!chr!" lss "吖" (
- set "PY=!PY!!chr!"
- ) else (
- for %%c in (!chr!) do if "!inds:%%c=!" neq "%inds%" (
- for /f "skip=1 delims=:" %%a in ('(echo !inds!!chr!^)^|sort^|findstr /n "!chr!"') do set "PY=!PY! !$%%a! "
- ) else (
- for /f "delims=:" %%a in ('(echo !inds!!chr!^)^|sort^|findstr /n "!chr!"') do set "PY=!PY! !$%%a! "
- )
- )
- )
- set str
- set PY
- pause
- exit
-
-
- :init
- set "cnt=1"
- for %%a in (
- 吖a 哎ai 安an 肮ang 凹ao 八ba 挀bai 扳ban 邦bang 勹bao 萡be 陂bei 奔ben 伻beng 皀bi
- 边bian 标biao 憋bie 汃bin 仌bing 癶bo 卜bu 攃ca 猜cai 参can 仓cang 撡cao 刂ce 岑cen 噌ceng
- 叉cha 犲chai 觇chan 伥chang 抄chao 车che 抻chen 阷cheng 吃chi 冲chong 抽chou 出chu 欻chua 揣chuai 川chuan
- 刅chuang 吹chui 杶chun 逴chuo 呲ci 匆cong 凑cou 粗cu 汆cuan 崔cui 邨cun 搓cuo 咑da 呆dai 亻dan
- 当dang 刀dao 恴de 揼den 灯deng 仾di 嗲dia 敁dian 刁diao 爹die 丁ding 丟diu 东dong 吺dou 剢du
- 剬duan 垖dui 吨dun 多duo 妸e 诶ei 奀en 鞥eng 儿er 发fa 帆fan 匚fang 飞fei 分fen 丰feng
- 仏fo 紑fou 夫fu 旮ga 侅gai 甘gan 冈gang 皋gao 戈ge 给gei 根gen 刯geng 工gong 勾gou 估gu
- 瓜gua 乖guai 关guan 光guang 归gui 衮gun 呙guo 哈ha 还hai 佄han 夯hang 蒿hao 诃he 黒hei 拫hen
- 亨heng 叿hong 齁hou 乎hu 花hua 怀huai 欢huan 巟huang 灰hui 昏hun 吙huo 丌ji 加jia 戋jian 江jiang
- 艽jiao 阶jie 巾jin 仱jing 坰jiong 丩jiu 圧ju 姢juan 撅jue 军jun 咔ka 开kai 刊kan 闶kang 尻kao
- 苛ke 肎ken 劥keng 空kong 抠kou 扝ku 夸kua 蒯kuai 宽kuan 匡kuang 亏kui 坤kun 扩kuo 垃la 来lai
- 兰lan 啷lang 捞lao 仂le 雷lei 塄leng 唎li 嫾lian 簗liang 蹽liao 毟lie 拎lin 伶ling 溜liu 囖lo
- 龙long 瞜lou 撸lu 峦luan 掠lue 抡lun 啰luo 驴lv 略lve 妈ma 埋mai 颟man 牤mang 猫mao 孭me
- 沒mei 椚men 擝meng 咪mi 芇mian 喵miao 吀mie 民min 名ming 谬miu 摸mo 哞mou 呒mu 乸na 腉nai
- 囡nan 囔nang 孬nao 讷ne 馁nei 嫩nen 能neng 妮ni 拈nian 娘niang 鸟niao 捏nie 脌nin 宁ning 牛niu
- 农nong 羺nou 奴nu 奻nuan 挪nuo 女nv 噢o 讴ou 帊pa 拍pai 眅pan 乓pang 抛pao 呸pei 喷pen
- 匉peng 丕pi 囨pian 剽piao 氕pie 拼pin 乒ping 攴po 剖pou 扑pu 七qi 掐qia 扦qian 羌qiang 悄qiao
- 切qie 钦qin 青qing 卭qiong 丘qiu 区qu 奍quan 炔qv 夋qun 冄ran 穣rang 荛rao 惹re 人ren 扔reng
- 日ri 戎rong 禸rou 邚ru 撋ruan 甤rui 闰run 叒ruo 仨sa 毢sai 三san 桒sang 掻sao 色se 森sen
- 僧seng 杀sha 筛shai 山shan 伤shang 捎shao 奢she 申shen 升sheng 尸shi 収shou 殳shu 刷shua 衰shuai 闩shuan
- 双shuang 谁shui 吮shun 说shuo 厶si 忪song 凁sou 苏su 狻suan 夊sui 孙sun 莏suo 他ta 咍tai 坍tan
- 汤tang 仐tao 忑te 膯teng 剔ti 天tian 旫tiao 帖tie 厅ting 囲tong 偷tou 凸tu 猯tuan 推tui 吞tun
- 乇tuo 屲wa 歪wai 弯wan 尪wang 危wei 昷wen 翁weng 挝wo 乌wu 夕xi 虾xia 仙xian 乡xiang 灲xiao
- 些xie 心xin 星xing 凶xiong 休xiu 戌xu 吅xuan 削xv 坃xun 丫ya 咽yan 央yang 幺yao 耶ye 一yi
- 乚yin 応ying 哟yo 佣yong 优you 迂yu 囦yuan 曰yv 晕yun 帀za 灾zai 兂zan 赃zang 遭zao 则ze
- 贼zei 怎zen 増zeng 扎zha 夈zhai 枬zhan 弡zhang 钊zhao 蜇zhe 贞zhen 凧zheng 之zhi 中zhong 舟zhou 朱zhu
- 抓zhua 跩zhuai 专zhuan 妆zhuang 隹zhui 迍zhun 拙zhuo 孖zi 宗zong 邹zou 租zu 劗zuan 厜zui 尊zun 昨zuo
- ) do (
- set "tt=%%a"
- set "inds=!inds!!tt:~0,1!&echo;"
- set /a cnt+=1
- set "$!cnt!=!tt:~1!"
- )
- exit /b
复制代码
作者: CrLf 时间: 2015-8-11 20:18
回复 11# aa77dd@163.com
哈,这思路也不错,算法好记
zuo 音的最后一个字是咗
整个列表顺序是这样的:- ○ ling
- 吖 a|ya
- ...
- 咗 zo|zuo
- 乤 hal
复制代码
作者: CrLf 时间: 2015-8-11 20:28
回复 11# aa77dd@163.com
我想也可以考虑先全部拆字输出,然后排序解析,在伪hash表中为每个字设置对应拼音,再回过头来逐字处理,这样算法会变得比较复杂,但能节省反复运行 sort.exe 和 findstr.exe 的耗时
作者: MCRGZN 时间: 2015-8-13 17:18
不错不错不错不错不错
作者: MCRGZN 时间: 2015-8-13 17:19
不错不错不错不错不错
作者: wskwfkbdn 时间: 2016-1-19 00:00 标题: 标题
回复 1# CrLf
纯p的文字转拼音挺不错,如果是 “简123单”,你看转转结果怎么样。
作者: CrLf 时间: 2016-1-19 01:05
回复 16# wskwfkbdn
测试得到的输出如下:复制代码
好像没遇到问题
作者: wskwfkbdn 时间: 2016-1-19 13:50
回复 17# CrLf
挺好的,赞 +1
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |