[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] 批处理计算字符串相似度

看到这个贴子http://www.bathome.net/thread-69920-1-1.html有字符串相似的相关问题,
于是结合编辑距离和公共子串序相关的算法写了三种方法计算字符相似度,各有侧重
  1. @echo off
  2. call :sim "abcd你好123" "bd好运1314"
  3. call :sim "abcd你好123" "abcd你好132&"
  4. pause&exit
  5. :sim
  6. if "%~1"=="" if not "%~2"=="" (echo,---0%%---&exit /b)
  7. if "%~2"=="" if not "%~1"=="" (echo,---0%%---&exit /b)
  8. if "%~2"==""     if "%~1"=="" (echo,---100%%---&exit /b)
  9. set "str1=%~1"&set "_str1=%~1#"
  10. set "str2=%~2"&set "_str2=%~2#"
  11. setlocal enabledelayedexpansion
  12. for %%i in (2048 1024 512 256 128 64 32 16 8 4 2 1) do (
  13.     if not "!_str1:~%%i,1!"=="" (set /a "len1+=%%i"&set "_str1=!_str1:~%%i!")
  14.     if not "!_str2:~%%i,1!"=="" (set /a "len2+=%%i"&set "_str2=!_str2:~%%i!")
  15.    )
  16. set /a _len1_=len1+1,_len2_=len2+1
  17. setlocal
  18. for /l %%i in (0,1,%_len1_%) do set /a count[%%i][0]=%%i
  19. for /l %%i in (0,1,%_len2_%) do set /a count[0][%%i]=%%i
  20. for /l %%i in (1,1,%_len1_%) do (
  21.     for /l %%j in (1,1,%_len2_%) do (
  22.         set /a ci=%%i-1,cj=%%j
  23.         set /a c1=count[!ci!][!cj!]+1
  24.         set /a ci=%%i,cj=%%j-1
  25.         set /a c2=count[!ci!][!cj!]+1
  26.         set /a ci=%%i-1,cj=%%j-1
  27.         set /a c3=count[!ci!][!cj!]
  28.         set /a ii=%%i-1,jj=%%j-1
  29.         call :cut !ii! !jj!
  30.         if not "!s1!"=="!s2!" set /a c3+=1
  31.         if !c1! leq !c2! (set /a min=c1) else set /a min=c2
  32.         if !c3! leq !min! (set /a count[%%i][%%j]=c3) else set /a count[%%i][%%j]=min
  33.     )
  34. )
  35. set /a dist=count[%len1%][%len2%]
  36. endlocal&set /a dist=%dist%
  37. setlocal
  38. for /l %%i in (1,1,%_len1_%) do (
  39.     for /l %%j in (1,1,%_len2_%) do (
  40.         set /a ii=%%i-1,jj=%%j-1
  41.         call :cut !ii! !jj!
  42.         set /a ci=%%i-1,cj=%%j-1
  43.         if "!s1!"=="!s2!" (
  44.             set /a count[%%i][%%j]=count[!ci!][!cj!]+1
  45.         ) else (
  46.             set /a c1=count[!ci!][!cj!]
  47.             set /a ci=%%i-1,cj=%%j
  48.             set /a c2=count[!ci!][!cj!]
  49.             set /a ci=%%i,cj=%%j-1
  50.             set /a c3=count[!ci!][!cj!]
  51.             if !c1! geq !c2! (set /a max=c1) else set /a max=c2
  52.             if !c3! geq !max! (set /a count[%%i][%%j]=c3) else set /a count[%%i][%%j]=max
  53.         )
  54.     )
  55. )
  56. set /a LCS=count[%len1%][%len2%]
  57. endlocal&set /a LCS=%LCS%
  58. setlocal
  59. set /a matches=0
  60. if %len1% geq %len2% (
  61.     set "maxStr=!str1!"&set "minStr=!str2!"
  62.     set /a maxLen=len1,minLen=len2
  63. ) else (
  64.     set "maxStr=!str2!"&set "minStr=!str1!"
  65.     set /a maxLen=len2,minLen=len1
  66. )
  67. set /a "match_max=maxLen/2-1"
  68. if !match_max! leq 0 set /a match_max=0
  69. set /a _minLen_=minLen-1
  70. for /l %%i in (0,1,%_minLen_%) do (
  71.     set "minChar=!minStr:~%%i,1!"
  72.     set /a jj=%%i-match_max
  73.     if !jj! leq 0 set /a jj=0
  74.     set /a jj_lim=%%i+match_max+1
  75.     if !jj_lim! geq !maxLen! set /a jj_lim=maxLen
  76.     set /a jj_lim-=1
  77.     for /l %%j in (!jj!,1,!jj_lim!) do (
  78.         set /a maxflag[%%j]=maxflag[%%j]
  79.         set "maxChar=!maxStr:~%%j,1!"
  80.         if !flag[%%j]! equ 0 if "!minChar!"=="!maxChar!" (set /a maxflag[%%j]=1,minflag[%%i]=1,matches+=1)
  81.     )
  82. )
  83. set /a trans=jj=0
  84. for /l %%i in (0,1,%_minLen_%) do (
  85.     if !minflag[%%i]! equ 1 (
  86.         for /l %%j in (!jj!,1,!jj_lim!) do if "!maxflag[%%j]!" equ 0 (set /a jj+=1)
  87.         for %%j in (!jj!) do if not "!minStr:~%%i,1!"=="!maxStr:~%%j,1!" (set /a trans+=1)
  88.         set /a jj+=1
  89.     )
  90. )
  91. set /a trans/=2
  92. if %matches% equ 0 (endlocal&set/a simPCT3=0&goto :end)
  93. set /a "jaro=(matches*100/len1+matches*100/len2+((matches-trans)*100/matches))/3"
  94. endlocal&set /a simPCT3=%jaro%
  95. :end
  96. if %len1% geq %len2% (set /a maxLen=len1) else set /a maxLen=len2
  97. set /a "simPCT1=LCS*100/maxLen"
  98. set /a "simPCT2=LCS*100/(%dist%+%LCS%)"
  99. echo,---%simPCT1%%%---%simPCT2%%%---%simPCT3%%%---"!str1!"与"!str2!"相似度
  100. exit /b
  101. :cut
  102. set "s1=!str1:~%1,1!"
  103. set "s2=!str2:~%2,1!"
复制代码
1

评分人数

搞算法的都是牛人.
微信:flashercs
QQ:49908356

TOP

回复 2# flashercs


    哈哈,是的,都是那帮牛人研究出来的。算法的本质就是数学,研究算法会涉及很多数学和数据结构方面的东西。

TOP

我看不懂这算法,我这老年人也搞不了算法了...
微信:flashercs
QQ:49908356

TOP

返回列表