在一个字符串中计算特定字符出现的次数

73
什么是在字符串中计算特定字符出现次数的最简单方法?
也就是说,我需要编写一个名为countTheCharacters()的函数,以便进行计数。
str = "the little red hen"
count = countTheCharacters(str,"e") ' Count should equal 4
count = countTheCharacters(str,"t") ' Count should equal 3

最快的方法不是使用字符串。如果您真的对速度感兴趣,应该寻找其他东西。 - habakuk
1
@habakuk,除了“小红母鸡”之外,OP可以使用哪些非字符串值? - johny why
26个回答

81

最简单的方法是直接遍历字符串中的每个字符:

Public Function CountCharacter(ByVal value As String, ByVal ch As Char) As Integer
  Dim cnt As Integer = 0
  For Each c As Char In value
    If c = ch Then 
      cnt += 1
    End If
  Next
  Return cnt
End Function

使用方法:

count = CountCharacter(str, "e"C)

另一种几乎同样有效并且代码更短的方法是使用LINQ扩展方法:

Public Function CountCharacter(ByVal value As String, ByVal ch As Char) As Integer
  Return value.Count(Function(c As Char) c = ch)
End Function

1
我来这里是为了寻找最快的方法,而不一定是最优雅的方法。这个方法很快,但是可以通过使用For i as Integer = 0 to value.Length - 1而不是For Each循环来使其快大约10%。 - NightOwl888
'Count' is not a member of 'String'. - Panzercrisis
1
@Panzercrisis:Count 方法是 IEnumerable<T> 的扩展方法,而 String 实现了 IEnumerable<char>。如果你遇到这样的编译器错误,那么你可能在页面顶部缺少了 using System.Linq; 引用。 - Guffa
2
这个逻辑也可以用于VBA:Public Function CountCharacter(ByVal value As String, ByVal ch As Char) As Integer Dim cnt As Integer For Each c In value If c = ch Then cnt = cnt + 1 End If Next CountCharacter = cnt End Function - Reverend_Dude
你不喜欢简洁明了吗!我爱上了使用 Linq 的最后一个例子:Dim countChar As Char = "o" Dim count As Integer = myString.Count(Function(c As Char) c = countChar)``` - JohnRDOrazio
2
答案和评论中的代码不能直接粘贴到VBA中并在第一次尝试时运行。以下是一些VBA代码,以防有人需要:Private Function CountCharacter(WhatToSearch As String, SearchForThis As String) As Long Dim NumberOfHits As Long Dim i As Long For i = 1 To Len(WhatToSearch) If Mid(WhatToSearch, i, 1) = SearchForThis Then NumberOfHits = NumberOfHits + 1 End If Next CountCharacter = NumberOfHits End Function - RedDragonWebDesign

72
这是一种简单的方法:
text = "the little red hen"
count = text.Split("e").Length -1 ' Equals 4
count = text.Split("t").Length -1 ' Equals 3

2
如果起始字母和/或结束字母是要计数的字母,则这并不总是给出正确的数字。 - Reman
1
@Remonn 对我来说它总是给出正确的数字。唯一不计算起始/结束字母的方法是将 SplitStringOptions.RemoveEmptyEntries 作为 Split() 的第二个参数传递。 - alldayremix
1
这很简单,但它创建了一堆甚至没有用途的字符串。 - Guffa
@Guffa,由于split函数并未应用于变量上,分配给split的任何内存是否会立即释放取决于具体的编程语言,我想是这样的。 - johny why
2
@johnywhy:内存不会立即释放,字符串会一直保留在内存中,直到垃圾回收器可以收集它们。短寿命对象非常普遍,垃圾回收器被优化为高效处理它们,但它们仍然增加了分配吞吐量,并为垃圾回收器带来更多工作。这由框架处理,因此对于所有.NET语言都是相同的。 - Guffa
谢谢。这个想法对于VBA也非常有效! count = ubound(Split("the little red hen","e") '等于4 - Marcelo Scofano Diniz

36
你可以尝试这个。
Dim occurCount As Integer = Len(testStr) - Len(testStr.Replace(testCharStr, ""))

4
把你的答案除以 Len(testCharStr),然后向上取整,这样也可以适用于字符串出现次数的情况。 - Nikhil Agrawal
这种方法的好处是它使用非常基本的函数,没有LINQ、RegEx或其他额外的库。可以轻松地在各种语言中复制。 - johny why

22

这是一个简化版。

text.count(function(x) x = "a")

以上代码将会给出字符串中a的数量。如果您想忽略大小写:

text.count(function(x) Ucase(x) = "A")

或者如果您只想计算字母:

text.count(function(x) Char.IsLetter(x) = True)

试一试吧!


这对我来说看起来不像是一个vb.net的解决方案。 - Jonny
这是一个非常VB.NET的解决方案! - Adam
失败了。我的VS 2017没有字符串的.count方法。 - Doug Null
@DougNull 我已经不再从事VB和.Net开发。我回家后可能会试着弄一下。你尝试过导入Linq吗?我在想那是否会有所不同。我可以向你保证,这对我和过去的其他人都起作用,但你会注意到解决方案是在2014年发布的。我不知道自那时以来是否发生了破坏这个问题的变化。如果真是这样的话,那对我来说会很失望。这可能只是lambda表达式实现方式的更改? - MattB

7
感谢您,@guffa。在.NET中能够一行代码或者在更长的语句中完成是非常方便的。这个VB.NET示例计算了换行符的数量:
Dim j As Integer = MyString.Count(Function(c As Char) c = vbLf)

j返回MyString中换行符的数量。


5
或者(在VB.NET中):
Function InstanceCount(ByVal StringToSearch As String,
                       ByVal StringToFind As String) As Long
    If Len(StringToFind) Then
        InstanceCount = UBound(Split(StringToSearch, StringToFind))
    End If
End Function

5
将Ujjwal Manandhar的代码转换为VB.NET如下...
Dim a As String = "this is test"
Dim pattern As String = "t"
Dim ex As New System.Text.RegularExpressions.Regex(pattern)
Dim m As System.Text.RegularExpressions.MatchCollection
m = ex.Matches(a)
MsgBox(m.Count.ToString())

谢谢,我选择这个版本。看起来非常快速。实际上,我正在搜索文本字符串中的CR和/或LF以及频率,以便可以调整Gridview中文本框的大小和高度以支持输出。 - htm11h

3
我认为这是最简单的方法:
Public Function CountCharacter(ByVal value As String, ByVal ch As Char) As Integer
  Return len(value) - len(replace(value, ch, ""))
End Function

2
我建议您这样做:

String.Replace("e", "").Count
String.Replace("t", "").Count

你也可以分别使用.Split("e").Count - 1.Split("t").Count - 1,但如果字符串开头有e或t,它会给出错误的值。


1
这是 VB.NET 吗?我没有安装 Visual Studio,但是 dotnetfiddle.net 和 ideone.com 都报告“'count' 不是 'String' 的成员。” - johny why

2
Public Function CountOccurrences(ByVal StToSerach As String, ByVal StToLookFor As String) As Int32

    Dim iPos = -1
    Dim iFound = 0
    Do
        iPos = StToSerach.IndexOf(StToLookFor, iPos + 1)
        If iPos <> -1 Then
            iFound += 1
        End If<br/>
    Loop Until iPos = -1
    Return iFound
End Function

代码使用:

Dim iCountTimes As Integer = CountOccurrences("Can I call you now?", "a")

你也可以将其作为扩展程序来使用:

<Extension()> _
Public Function CountOccurrences(ByVal StToSerach As String, ByVal StToLookFor As String) As Int32
    Dim iPos = -1
    Dim iFound = 0
    Do
        iPos = StToSerach.IndexOf(StToLookFor, iPos + 1)
        If iPos <> -1 Then
            iFound += 1
        End If
    Loop Until iPos = -1
    Return iFound
End Function

代码使用:

Dim iCountTimes2 As Integer = "Can I call you now?".CountOccurrences("a")

1
在 Stack Overflow 上,您可以使用编辑器中的 {} 按钮格式化代码。这次我已经为您进行了编辑。 - Flexo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接