Visual Basic - Technik, FAQ, Tricks, Beispiele

Home / Daten / Strings / Repeat

Texte wiederholen

Historie
11.12.2000Parameter-Reihenfolge getauscht (ist jetzt dieselbe wie bei der String$-Funktion)
08.12.2000Nach Anregung von Donald Lessau (VBSpeed): Ohne Schleife ist diese Version doppelt so schnell
20.07.2000Erste Version: 1000-mal schneller als der naive Ansatz
Soll ein Text mehrfach hintereinander geschrieben werden (z.B. 4 mal "bla " soll "bla bla bla bla " ergeben), so sind verschiedene Möglichkeiten denkbar:

Handelt es sich bei dem Text nur um einen Buchstaben, so kann die in VB eingebaute String$-Funktion verwendet werden. Beispielsweise gibt String$(5, "x") gerade "xxxxx" zurück.

Ist der zu vermehrende Text jedoch länger als 1 Zeichen, so muss selbst programmiert werden. Die erste Idee ist typischerweise das wiederholte Anhängen des Textes mit dem &-Operator, z.B. so:
Function StrRepeat( _
    ByVal nCount As Long, _
    ByRef sText As String _
  ) As String

  For nCount = 1 To nCount
    StrRepeat = StrRepeat & sText
  Next nCount
End Function
Diese Funktion macht genau das gewünschte: StrRepeat("[-]", 3) ergibt "[-][-][-]". Allerdings läßt die Performance (insbesondere bei vielen Wiederholungen) zu wünschen übrig. Das Problem: Für jede Wiederholung legt VB intern einen neuen String an, der auch noch immer länger wird. Gerade dies kostet in VB viel Zeit.

Daher soll hier eine andere Idee realisiert werden: Es wird (mit der Space$-Funktion) gleich ein String der richtigen Länge angelegt (ergibt sich aus der Länge des Textes und der Anzahl der Wiederholungen). Dann braucht nur noch an den richtigen Positionen (abhängig von der Textlänge) der Text in den String rein geschrieben werden. Dies geschieht mit dem wenig bekannten Mid$-Statement, welcher keinerlei String-Erzeugung seitens VB verursacht:
Function StrRepeat( _
    ByVal nCount As Long, _
    ByRef sText As String _
  ) As String

  'Platz reservieren:
  StrRepeat = Space$(Len(sText) * nCount)

  'Text in die richtigen Positionen kopieren:
  For nCount = 1 To Len(StrRepeat) Step Len(sText)
    Mid$(StrRepeat, nCount) = sText
  Next nCount
End Function
Bei meinen Tests (mit 1.000.000 Wiederholungen) ergab sich dadurch eine Beschleunigung auf mehr als das 1000-fache!

Und es geht noch besser (gut doppelt so schnell): VB kopiert nämlich bei einer Zuweisung mit Mid$ Zeichen für Zeichen (von vorne nach hinten). Daher funktioniert (wider erwarten) der unten stehende Code genau wie gewünscht:
Function StrRepeat( _
    ByVal nCount As Long, _
    ByRef sText As String _
  ) As String

  'Abbruch, falls keine Wiederholungen:
  If nCount < 1 Then Exit Function

  'Abbruch bei Leerstring:
  If Len(sText) < 1 Then Exit Function

  If Len(sText) > 1 Then
    'Platz reservieren:
    StrRepeat = Space$(Len(sText) * nCount)

    'Text in erste Position kopieren:
    Mid$(StrRepeat, 1) = sText

    'Ggf. Rest durch Selbst-Kopie erledigen:
    If nCount > 1 Then Mid$(StrRepeat, Len(sText) + 1) = StrRepeat
  Else
    StrRepeat = String$(nCount, sText)
  End If
End Function
Man beachte, dass keine Schleife mehr benötigt wird.

© Jost Schwider, 20.07.2000-11.12.2000 - http://vb-tec.de/srepeat.htm