Optimale Substring Zählung

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    Optimale Substring Zählung

    Hallo,

    Ich möchte in einem String einen Substring zählen. Das ganz brauche ich sehr oft, weshalb ich da eine möglichst gute Funktion für basteln möchte.

    Im Moment nehme ich LINQ:

    VB.NET-Quellcode

    1. Private Function Suche(source As String, target As String) As Integer
    2. If Not source.Contains(target) Then Return 0
    3. source = source.Replace(target, "*")
    4. Dim chars = source.ToCharArray
    5. Return chars.Count(Function(x) x = "*")
    6. End Function

    Lohnt es sich das als Extension zu machen? Ich weiß nicht warum das in einem extra Modul sitzen muss und ob sich das auf die Funktion auswirkt, wäre natürlich schöner zu tippen.

    Viele Grüße

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Da ich inzwischen sehr viele Extensions habe, stört mich auch nicht, dass ich dafür ein Module brauche. Je häufiger Du es brauchst, desto eher rate ich an solch einer Stelle zu einer Extension. Mir gefallen die Dinger.
    Wenn Dein source-String von Haus aus ein * enthält, wird's falsch.
    Mit IndexOf bekommst Du entweder -1 bei Nichtauffinden oder die Position des ersten Auffindens. Du könntest nach dem ersten Auffinden den String an dieser Stelle kürzen und dann wieder suchen. Gibt aber bestimmt noch bessere Wege.

    z.B.:

    VB.NET-Quellcode

    1. <Extension>
    2. Private Function OccurencesOf(source As String, target As String) As Integer
    3. Dim StartLength = source.Length
    4. Dim EndLength = source.Replace(target, String.Empty).Length
    5. Dim Difference = StartLength - EndLength
    6. Dim Occurences = Difference \ target.Length
    7. Return Occurences
    8. End Function

    Also den Suchtext beseitigen und aufgrund der Textlängenveränderung ermitteln, wie oft der Text drin war.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Stellt sich noch die Frage, welches Ergebnis Du hier erwartest:
    source = "aaaaaa"
    target = "aaa"
    Soll da 2 rauskommen oder 4?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Was'n das für ne nichtfunktionierende Option Strict Off-Version?
    Oder ist da ne Extension von Dir? So eine hab ich auch. Aber sowas sollte in der Lösung angegeben werden, dass das keine offizielle Split-Überladung ist.

    ##########

    die offizielle Variante wäre eher:

    VB.NET-Quellcode

    1. Return source.Split({target}, StringSplitOptions.None).Length - 1

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VaporiZed“ ()

    Dann müsstest Du den String 2x testen. 1x mit einer der o.g. Varianten und 1x z.B. mit

    VB.NET-Quellcode

    1. Private Function OverlappingOccurencesOf(source As String, target As String) As Integer
    2. Dim Occurences = 0
    3. Dim CurrentPosition = 0
    4. Do
    5. Dim NextPosition = source.IndexOf(target, CurrentPosition)
    6. If NextPosition = -1 Then Return Occurences
    7. Occurences += 1
    8. CurrentPosition = NextPosition + 1
    9. Loop
    10. End Function

    Und wenn bei beiden Verfahren unterschiedliche Werte rauskommen, dann meckern, also z.B.:

    VB.NET-Quellcode

    1. <Extension> Public Function OccurencesOf(source As String, target As String) As Integer
    2. Dim Result1 = NonOverlappingOccurencesOf(source, target)
    3. Dim Result2 = OverlappingOccurencesOf(source, target)
    4. If Result1 <> Result2 Then Throw New ArgumentException("Der Suchstring ist - abhängig vom Suchverfahren - unterschiedlich oft im Originaltext enthalten.")
    5. Return Result1
    6. End Function
    7. Private Function NonOverlappingOccurencesOf(source As String, target As String) As Integer
    8. Return source.Split({target}, StringSplitOptions.None).Length - 1
    9. End Function
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.