8楼的代码,因为findstr 的一些特性,存在一些bug,修改如下:
一、词库搜索代码:
findstr /x /g:fen.tmp /f:dics.txt
二、把词库按字数分别存放,并且文件名上可见词的字数。如:
[email=dict@1.txt]dict@1.txt[/email]
1人
1们
...
[email=dict@2.txt]dict@2.txt[/email]
2人民
2后门
...
......
些种办法把词分出来后,可方便词库的维护。
以下代码可把楼主提供的词库转换成按字数分文档存放。- @echo off&setlocal enabledelayedexpansion
-
- for /l %%a in (0,1,10) do del dict@%%a.txt /q
-
- echo;%time%
- for /f "tokens=*" %%a in (dic16.txt) do (
- set str=%%a
- if "!str:~9!" equ "" (
- set str=0123456789%%a
- set n=!str:~-10,1!
- echo;!n!%%a>>dict@!n!.txt
- ) else (
- echo;!n!%%a>>dict@10.txt
- )
- )
- (for /f %%a in (dictionar@1.txt) do (echo;1%%a))>dict@1.txt
- dir /o-n /b dict@*>dics.txt
- echo;%time%
- pause
复制代码 三、dics.txt 存放各分词库的文件名,以字数长的分词库在前,短在后。
dics.txt内容:
[email=dict@10.txt]dict@10.txt[/email]
[email=dict@9.txt]dict@9.txt[/email]
[email=dict@8.txt]dict@8.txt[/email]
[email=dict@7.txt]dict@7.txt[/email]
[email=dict@6.txt]dict@6.txt[/email]
[email=dict@5.txt]dict@5.txt[/email]
[email=dict@4.txt]dict@4.txt[/email]
[email=dict@3.txt]dict@3.txt[/email]
[email=dict@2.txt]dict@2.txt[/email]
[email=dict@1.txt]dict@1.txt[/email]
四、分词代码修改后,不再有搜索漏网的bug。并且对速度影响不大,20个字数长度的句子,拆分用时在一秒内。- @echo off&setlocal enabledelayedexpansion
-
- :lp
- set str=
- echo;
- echo;直接回车退出测试
- set /p str=输入一个字符串:
- set ti=%time%
- if "!str!" equ "" goto :eof
- setlocal enabledelayedexpansion
-
-
- set/a z=8180,x=0&for /l %%a in (1,1,14) do (set/a "y=(z-x)/2+x"
- for %%b in (!y!) do if "!str:~%%b,1!" equ "" (set/a z=y) else (set/a x=y)
- )
- ::计算输入串的长度
-
- ::sap 存入同等长度的空格串
- set lens=1 2 3 4 5 6 7 8 9 10 11
- set/a z1=z-1
- set sap=
- (for /l %%i in (0,1,!z1!) do (
- set "spa= !spa!"
- set one=!str:~%%i,1! !one!
- set/a x=z-%%i
- for %%j in (!lens!) do (
- set/a y=%%i+%%j
- echo;%%j!str:~%%i,%%j!
- for %%a in ("!str:~%%i,%%j!") do (
- set ##%%~a=%%i-!y!-%%j !##%%~a!
- )
- )
- ))>fen.tmp
-
- ::(for /l %%a in (0,1,!z!) do for %%k in (!@%%a!) do (echo;%%k))>fen.tmp
- ::进行排列拆分到临时文件fen.tmp,同时取各分词的长度,及在原句中的起址位置,并按一定的规则保存
- ::似乎要从短到长,findstr才能完全正确查找
-
-
- set var=!str!
- echo;!vvv!
-
- for /f "tokens=2* delims=:123456789" %%1 in ('findstr /x /g:fen.tmp /f:dics.txt') do (
- for %%k in (!##%%2!) do (
- if "!var:%%2=!" neq "!var!" (
- for /f "tokens=1,2,3 delims=-" %%b in ("%%k") do (
- if "!var:~%%b,%%d!" equ "!str:~%%b,%%d!" (
- echo;截取过程:[!var!] %%2
- set var=!var:~0,%%b!!spa:~,%%d!!var:~%%c!
- set $$%%b= [%%2]
- )
- )
- )
- )
- )
- ::搜索词库,并做已经截取过记号,同时为恢复分词在原句中的位置做准备
-
-
- echo;
- if "!var: =!" neq "" (
- echo;词库中没有的:
- for %%a in (!var!) do (
- for %%k in (!##%%a!) do (
- if "!var:%%a=!" neq "!var!" (
- for /f "tokens=1,2,3 delims=-" %%b in ("%%k") do (
- if "!var:~%%b,1!" neq " " (
- echo;截取过程:[!var!] %%a
- set var=!var:~0,%%b!!spa:~,%%d!!var:~%%c!
- set $$%%b= %%a
- )
- )
- )
- )
- )
- ) else (echo;所有字符均可在词库中找到)
- ::对在词库中找不到的分词,也进行同样的处理
-
- echo;
- set dest=
- for /l %%a in (0,1,!z!) do set dest=!dest!!$$%%a!
- echo;最终拆分:!dest!
- echo;%ti%
- echo;%time%
- endlocal&goto :lp
复制代码 五、词在库中的先后,决定了匹配的优先顺序,只要改变词在库中的顺序,即可改变折分的准确性。
我另外写了一个词库维护的代码,可以改变词在库中的顺序,增加词到词库中。
初版只支持一次修改两个词顺序。代码如下:- @echo off&setlocal enabledelayedexpansion
-
- echo; ** 调整词序/增加词组 **
- set /p str1=输入第一字符串:
- set /p str2=输入第二字符串:
- if "!str1!" equ "!str2!" goto :eof
-
- set str=0123456789!str1!
- set n1=!str:~-10,1!
-
- set str=0123456789!str2!
- set n2=!str:~-10,1!
-
- set str1=!n1!!str1!
- set str2=!n2!!str2!
-
- if "!n1!" equ "!n2!" (
- findstr /x "!str1!" dict@!n1!.txt>nul
- if !errorlevel! equ 1 (
- set str1=%str2%
- set str2=%str1%
- set xchg=y
- findstr /x "!str1!" dict@!n1!.txt>nul
- if !errorlevel! equ 1 set xchg=n
- )
-
- if "!xchg!" neq "n" (
- copy dict@!n1!.txt fen.tmp /y
- (for /f %%a in (fen.tmp) do (
- if "%%a" neq "!str2!" echo;%%a
- if "%%a" equ "!str1!" (
- echo;!str2!
- if defined xchg (echo;!str1!)
- )
- ))>dict@!n1!.txt
- echo;修改 [!str1!] 和 [!str2!] 在dict@!n1!.txt中的顺序
- ) else (
- echo;!str2!>>dict@!n1!.txt
- echo;!str1!>>dict@!n1!.txt
- echo;添加 [!str1!] 和 [!str2!] 到 dict@!n1!.txt
- )
-
- ) else (
- findstr /x "!str1!" dict@!n1!.txt>nul
- if !errorlevel! equ 1 (
- echo;!str1!>>dict@!n1!.txt
- echo;添加 [!str1!] 到 dict@!n1!.txt
- )
- findstr /x "!str2!" dict@!n2!.txt>nul
- if !errorlevel! equ 1 (
- echo;!str2!>>dict@!n2!.txt
- echo;添加 [!str2!] 到 dict@!n2!.txt
- )
- )
-
- pause
复制代码 拆分句子示例:
输入一个字符串:这也是造成肇事车辆屡屡逃逸的一个主要原因
截取过程:[这也是造成肇事车辆屡屡逃逸的一个主要原因] 主要原因
截取过程:[这也是造成肇事车辆屡屡逃逸的一个 ] 屡屡
截取过程:[这也是造成肇事车辆 逃逸的一个 ] 车辆
截取过程:[这也是造成肇事 逃逸的一个 ] 逃逸
截取过程:[这也是造成肇事 的一个 ] 一个
截取过程:[这也是造成肇事 的 ] 也是
截取过程:[这 造成肇事 的 ] 造成
截取过程:[这 肇事 的 ] 肇事
截取过程:[这 的 ] 这
截取过程:[ 的 ] 的
所有字符均可在词库中找到
最终拆分: [这] [也是] [造成] [肇事] [车辆] [屡屡] [逃逸] [的] [一个] [主要原因]
开始: 6:44:02.45
结束: 6:44:03.20
楼主出的测试例子结果如下(词库的一些词经过顺序调整):
最终拆分: [我] [喜欢] [坐在] [面包车] [上] [一边] [吃] [面包] [一边] [看] [北京] [天安门] [门楼] [的] [门]
最终拆分: [我] [喜欢] [坐在] [面包车] [上] [一边] [吃] [面包] [一边] [看] [北京] [大学生活动中心] [门楼] [的] [门]
最终拆分: [我] [喜欢] [坐在] [面包车] [上] [一边] [吃] [面包] [一边] [看] [北京大学] [生活] [在] [音乐] [里]
最终拆分: [我] [喜欢] [坐在] [面包车] [上] [一边] [吃] [面包] [一边] [看] [北京大学] [生活] [很好]
最终拆分: [我] [喜欢] [坐在] [面包车] [上] [一边] [吃] [面包] [一边] [看] [北京大学] [的] [学生] [生活] [在] [音乐] [里]
最终拆分: [我] [喜欢] [坐在] [面包车] [上] [一边] [吃] [面包] [一边] [看] [北京大学] [的] [学生] [活在] [音乐] [里]
最终拆分: [广西] [大学生活] [很好]
最终拆分: [我] [喜欢] [吃] [鸭肉]
最终拆分: [伟] [大学生] [生活]
最终拆分: [大学生活] [动]
最终拆分: [大学生活] [好]
最终拆分: [大学生活动中心]
最终拆分: [发展] [中国家庭养猪] [事业]
最终拆分: [你说] [的] [确实在] [理]
[ 本帖最后由 netbenton 于 2010-9-17 07:31 编辑 ] |