ExcelTip.Net留存知识帖 ---【注:附件之前被网盘供应商清空后,现已修复-现已修复-现已修复为本地下载!】
现在位置:首页 > E问E答 > Excel VBA > 如何求相同位置子字符串在所有字符串中的出现次数?

如何求相同位置子字符串在所有字符串中的出现次数?

作者:绿色风 分类: 时间:2022-08-17 浏览:125
楼主
amulee
Q:如何求相同位置子字符串在所有字符串中的出现次数?
A:如本例,各文本文件中含有许多字符串。取出各字符串中长度为1--文本长度的子字符串。求该子字符串在其他字符串中相同位置的出现次数。
     如某字符串1234567,其子字符串12,在其他字符串的相同位置如果也为12,则计数加1。
     最后再从所有提供的文本文件中求存在该子字符串的文本文件的个数。
     
     本例中,关键是要求长度为N的字符串的各种子字符串,可采用以下算法:
  1. LenA = 7
  2.     strPL = "1234567"
  3.     ReDim arrPL(1 To (LenA + 1) * LenA / 2)
  4.     For i = 1 To LenA
  5.         For j = 1 To LenA + 1 - i
  6.             k = k + 1
  7.             arrPL(k) = Mid$(strPL$, j, i)
  8.         Next j
  9.     Next i


本例完整代码如下:
  1. Sub GetN()
  2.     Dim arrPL() As String   '所有的数字段排列
  3.     Dim StrA$, strPL$, strTemp$, strPLTemp$
  4.     Dim LenA As Byte, i&, j&, k&, arrJG(), arrTxt()
  5.     Dim FName$, FS%, key, FCount%
  6.     '定义两个字典,一个为全局字典,记录所有的情况
  7.     '另一个为单个文件的字典,避免单个文件相同排列重复计数
  8.     Dim dAll As Object, dOne As Object
  9.     Set dAll = CreateObject("Scripting.Dictionary")
  10.     Set dOne = CreateObject("Scripting.Dictionary")
  11.     FName = Dir(ThisWorkbook.Path & Application.PathSeparator & "*.txt")
  12.     '文本长度
  13.     LenA = 7
  14.     t = Timer
  15.     '先给出所有排列的结果
  16.     strPL = "1234567"
  17.     ReDim arrPL(1 To (LenA + 1) * LenA / 2)
  18.     For i = 1 To LenA
  19.         For j = 1 To LenA + 1 - i
  20.             k = k + 1
  21.             arrPL(k) = Mid$(strPL$, j, i)
  22.         Next j
  23.     Next i
  24.     ReDim arrCount(1 To 1)
  25.     k = 0
  26.     '遍历所有Txt文件
  27.     Do While FName <> ""
  28.         FCount = FCount + 1
  29.         '清空单个字典
  30.         dOne.RemoveAll
  31.         '打开文本文件
  32.         FS = FreeFile
  33.         Open ThisWorkbook.Path & Application.PathSeparator & FName For Input As #FS
  34.         Do While Not EOF(FS)
  35.             Line Input #FS, StrA
  36.             '对数字进行各种排列
  37.             For i = 1 To UBound(arrPL)
  38.                 '取出一个排列
  39.                 strPLTemp = arrPL(i)
  40.                 strTemp = StrA
  41.                 '将文本的除当前排列保留部分的其他字符替换
  42.                 For j = 1 To LenA
  43.                     If InStr(strPLTemp, j) = 0 Then Mid(strTemp, j, 1) = "*"
  44.                 Next j
  45.                 '当前字典计数
  46.                 dOne(strTemp) = dOne(strTemp) + 1
  47.             Next i
  48.         Loop
  49.         '将本次结果加入全局字典
  50.         For Each key In dOne.keys
  51.             If dAll.exists(key) Then
  52.                 '如果全局字典中已经添加
  53.                 dAll(key) = dAll(key) & "," & Left(FName, Len(FName) - 4) & "(" & dOne(key) & ")"
  54.             Else
  55.                 dAll(key) = Left(FName, Len(FName) - 4) & "(" & dOne(key) & ")"
  56.             End If
  57.         Next
  58.         Close #FS
  59.         FName = Dir
  60.     Loop
  61.     '结果处理
  62.     For Each key In dAll.keys
  63.         If InStr(dAll(key), ",") = 0 Then
  64.             '如果只有一个
  65.             dAll(key) = Split(key & ",1," & dAll(key), ",")
  66.         Else
  67.             '如果有多个,则重新改写
  68.             '将数组结果写入
  69.             dAll(key) = Split(key & "," & UBound(Split(dAll(key), ",")) + 1 & "," & dAll(key), ",")
  70.         End If
  71.     Next
  72.     '结果输出
  73.     arrTxt = dAll.items
  74.     ReDim arrJG(UBound(arrTxt), FCount + 1)
  75.     For i = 0 To UBound(arrJG)
  76.         For j = 0 To UBound(arrTxt(i))
  77.             arrJG(i, j) = arrTxt(i)(j)
  78.         Next j
  79.     Next i
  80.     Range("B4").Resize(UBound(arrJG) + 1, FCount + 1) = arrJG
  81.     MsgBox Timer - t
  82. End Sub


附件下载:
如何求相同位置子字符串在所有字符串中的出现次数.rar
2楼
亡者天下
跟阿木老师学习VBA
3楼
qazwer168
鉴定完毕!

免责声明

有感于原ExcelTip.Net留存知识的价值及部分知识具有的时间限定性因素, 经与ExcelTip.Net站长Apolloh商议并征得其同意, 现将原属ExcelTip.Net的知识帖采集资料于本站点进行展示, 供有需要的人士查询使用,也慰缅曾经的论坛时代。 所示各个帖子的原作者如对版权有异议, 可与本人沟通提出,或于本站点留言,我们会尽快处理。 在此,感谢ExcelTip.Net站长Apolloh的支持,感谢本站点所有人**绿色风(QQ:79664738)**的支持与奉献,特此鸣谢!
------本人网名**KevinChengCW(QQ:1210618015)**原ExcelTip.Net总版主之一

评论列表
sitemap