how to find the number of occurrences of a substri

2019-01-14 18:04发布

I have a string (for example: "Hello there. My name is John. I work very hard. Hello there!") and I am trying to find the number of occurrences of the string "hello there". So far, this is the code I have:

Dim input as String = "Hello there. My name is John. I work very hard. Hello there!"
Dim phrase as String = "hello there"
Dim Occurrences As Integer = 0

If input.toLower.Contains(phrase) = True Then
    Occurrences = input.Split(phrase).Length      
    'REM: Do stuff
End If

Unfortunately, what this line of code seems to do is split the string every time it sees the first letter of phrase, in this case, h. So instead of the result Occurrences = 2 that I would hope for, I actually get a much larger number. I know that counting the number of splits in a string is a horrible way to go about doing this, even if I did get the correct answer, so could someone please help me out and provide some assistance?

12条回答
我欲成王,谁敢阻挡
2楼-- · 2019-01-14 18:19

You can create a Do Until loop that stops once an integer variable equals the length of the string you're checking. If the phrase exists, increment your occurences and add the length of the phrase plus the position in which it is found to the cursor variable. If the phrase can not be found, you are done searching (no more results), so set it to the length of the target string. To not count the same occurance more than once, check only from the cursor to the length of the target string in the Loop (strCheckThisString).

    Dim input As String = "hello there. this is a test. hello there hello there!"
    Dim phrase As String = "hello there"
    Dim Occurrences As Integer = 0

    Dim intCursor As Integer = 0
    Do Until intCursor >= input.Length

        Dim strCheckThisString As String = Mid(LCase(input), intCursor + 1, (Len(input) - intCursor))

        Dim intPlaceOfPhrase As Integer = InStr(strCheckThisString, phrase)
        If intPlaceOfPhrase > 0 Then

            Occurrences += 1
            intCursor += (intPlaceOfPhrase + Len(phrase) - 1)

        Else

            intCursor = input.Length

        End If

    Loop
查看更多
Animai°情兽
3楼-- · 2019-01-14 18:19

You could create a recursive function using IndexOf. Passing the string to be searched and the string to locate, each recursion increments a Counter and sets the StartIndex to +1 the last found index, until the search string is no longer found. Function will require optional parameters Starting Position and Counter passed by reference:

Function InStrCount(ByVal SourceString As String, _
                    ByVal SearchString As String, _
                    Optional ByRef StartPos As Integer = 0, _
                    Optional ByRef Count As Integer = 0) As Integer
    If SourceString.IndexOf(SearchString, StartPos) > -1 Then
        Count += 1
        InStrCount(SourceString, _
                   SearchString, _
                   SourceString.IndexOf(SearchString, StartPos) + 1, _
                   Count)
    End If
    Return Count
End Function

Call function by passing string to search and string to locate and, optionally, start position:

Dim input As String = "Hello there. My name is John. I work very hard. Hello there!"
Dim phrase As String = "hello there"
Dim Occurrences As Integer

Occurrances = InStrCount(input.ToLower, phrase.ToLower)

Note the use of .ToLower, which is used to ignore case in your comparison. Do not include this directive if you do wish comparison to be case specific.

查看更多
4楼-- · 2019-01-14 18:21

I don't know if this is more obvious? Starting from the beginning of longString check the next characters up to the number characters in phrase, if phrase is not found start looking from the second character etc. If it is found start agin from the current position plus the number of characters in phrase and increment the value of occurences

 Module Module1
Sub Main()

    Dim longString As String = "Hello there. My name is John. I work very hard. Hello there! Hello therehello there"

    Dim phrase As String = "hello There"


    Dim occurences As Integer = 0
    Dim n As Integer = 0

    Do Until n >= longString.Length - (phrase.Length - 1)
        If longString.ToLower.Substring(n, phrase.Length).Contains(phrase.ToLower) Then
            occurences += 1
            n = n + (phrase.Length - 1)
        End If
        n += 1
    Loop
    Console.WriteLine(occurences)


End Sub
End Module
查看更多
做自己的国王
5楼-- · 2019-01-14 18:25

Looking at your original attempt, I have found that this should do the trick as "Split" creates an array. Occurrences = input.split(phrase).ubound

This is CaSe sensitive, so in your case the phrase should equal "Hello there", as there is no "hello there" in the input

查看更多
贪生不怕死
6楼-- · 2019-01-14 18:26

Expanding on Sumit Kumar's simple solution (please upvote his answer rather than this one), here it is as a one-line working function:

Public Function fnStrCnt(ByVal str As String, ByVal substr As String) As Integer
    fnStrCnt = UBound(Split(LCase(str), substr))
End Function

Demo:

Sub testit()
    Dim thePhrase
    thePhrase = "Once upon a midnight dreary while a man was in a house in the usa."
    If fnStrCnt(thePhrase, " a ") > 1 Then
        MsgBox "Found " & fnStrCnt(thePhrase, " a ") & " occurrences."
    End If
End Sub 'testit()
查看更多
Animai°情兽
7楼-- · 2019-01-14 18:35

Yet another idea:

Dim input As String = "Hello there. My name is John. I work very hard. Hello there!"
Dim phrase As String = "Hello there"
Dim Occurrences As Integer = (input.Length - input.Replace(phrase, String.Empty).Length) / phrase.Length

You just need to make sure that phrase.Length > 0.

查看更多
登录 后发表回答