Problem mit rekursivem Vb(A) Code

Hi Alex,

Ich hab mir ehrlich gesagt darueber noch keinen Kopf gemacht.
Aber erstmal würde ich ueberprüfen ob die Anzahl der { gleich
der } sind.

gute Idee, habe ich nicht gemacht, dafür braucht uns Reinhard ja nicht. Deine Funktion aus der FAQ und gut ist’s. *fg*

Mit Instr würde gehen. Aber dazu muesste man erst die ganzen {
suchen und dann die entsprechenden }. Meinst du nicht das sich
das mit dem durchsuchen der einzelenen zeichen besser machen
würde, als immer instr zu verwenden und dann den Startwert
erhöhen und das in einer schleife solange bis der richtige
gefunden wurde?

Nein. Wenn die Zeichenketten zwischendurch etwas länger sind, eventuell ganze Texte, ist Instr() um ein vilefaches schneller.

Ist ein ziemliches Chaos wo sich schnell ein
Fehler einschleichen kann :frowning:

Na ja, ich habe ‚gemogelt‘ :smile: Ich ersetze die Klammern erst durch andere und beim Abarbeiten wieder durch die Richtigen, dann ergibt sich die richtige Zuordnung von selbst. Das ist extrem zuverlässig, aber sicher nicht der schnellste Code.

Mein Großer hat einen schnelleren mit C# geschrieben (mal programmieren üben) den kann ich auch nach VB übersetzen lassen, wenn es schneller gebraucht wird.

Habt ihr mal ein Testfile wo jeder mal testen kann, incl.
Zeitmessung. So koennten wir die schnellste Variante finden :wink:

Ich habe kein Testfile, ich habe mir nur den Beispielstring mit ein paar Zeichen getippt.

Gruß Rainer

Hallo Rainer,

gute Idee, habe ich nicht gemacht, dafür braucht uns Reinhard
ja nicht. Deine Funktion aus der FAQ und gut ist’s. *fg*

Ich weiss nicht ob ich die Function StrCount mit gepostet habe, die sich dafür anbietet, wenn nicht siehst du sie gleich :smile:

Nein. Wenn die Zeichenketten zwischendurch etwas länger sind,
eventuell ganze Texte, ist Instr() um ein vilefaches
schneller.

Ok, da hast du wiederrum Recht :smile:
Ich habe mal auf die schnelle etwas getippselt. Ich hoffe das es das ist was du suchst. kannst es mal bei dir laufen lassen und ne Zeitmessung machen, was schneller ist.

Das Bsp. ist mir nur auf die schnelle eingefallen :wink: und sicher noch optimierbar :wink: Naja schau es Dir mal an :smile:

Na ja, ich habe ‚gemogelt‘ :smile: Ich ersetze die Klammern erst
durch andere und beim Abarbeiten wieder durch die Richtigen,
dann ergibt sich die richtige Zuordnung von selbst. Das ist
extrem zuverlässig, aber sicher nicht der schnellste Code.

Nein, denn kannst du gewaehrleisten das das Zeichen nicht schon einmal irgendwo in dem Text da vorkommt ? Für mich waere das zu heikel und ich würde fein die {} Zeichen suchen :wink:

Ich habe kein Testfile, ich habe mir nur den Beispielstring
mit ein paar Zeichen getippt.

Teste mal bitte meine Variante und mache mal ne Zeitmessung. Mal schauen um wievieles meines langsamer ist :s

Option Explicit
Option Base 1

Private Declare Function ArrPtr Lib "msvbvm50.dll" Alias "VarPtr" (Ptr() As Any) As Long ' StrCount(MyData, "}") Then
 MsgBox "Ungleiche Klammernpaare!", 16
 Exit Sub
 End If
 ReDim vRet(Entry, 2)
 Call GetPos(MyData, vRet())
 Call GetData(MyData, vRet())
End Sub

Private Sub GetData(Text As String, vRet() As Long)
Dim i As Long
For i = 1 To UBound(vRet)
 Debug.Print Mid$(Text, vRet(i, 1), vRet(i, 2) - vRet(i, 1) + 1) 'Ausgabe mit geschweiften Klammern
Next i
Erase vRet
End Sub

Private Sub GetPos(Text As String, vRet() As Long)
Dim i As Long
Dim pos As Long
Dim x As Long
Dim merker As Long
pos = 1
For i = 1 To UBound(vRet)
 vRet(i, 1) = InStr(pos, Text, "{")
 x = vRet(i, 1) + 1
 merker = 0
 Do
 If Mid$(Text, x, 1) = "{" Then merker = merker + 1
 If Mid$(Text, x, 1) = "}" And merker = 0 Then
 vRet(i, 2) = x
 Exit Do
 ElseIf Mid$(Text, x, 1) = "}" And merker \> 0 Then
 merker = merker - 1
 End If
 x = x + 1
 Loop Until x \> Len(Text)
 pos = vRet(i, 1) + 1
Next i
End Sub

'Liefert die Anzahl eines Zeichens in einer Zeichenkette
Public Static Function StrCount(ByRef Text As String, ByRef Find As String, Optional ByVal Start As Long = 1, Optional ByVal Compare As VbCompareMethod = vbBinaryCompare) As Long
Const MODEMARGIN = 8
Dim TextAsc() As Integer
Dim TextData As Long
Dim TextPtr As Long
Dim FindAsc(0 To MODEMARGIN) As Integer
Dim FindLen As Long
Dim FindChar1 As Integer
Dim FindChar2 As Integer
Dim i As Long
 If Compare = vbBinaryCompare Then
 FindLen = Len(Find)
 If FindLen Then
 If Start FindAsc(i) Then Exit For
 Next i
 If i \> FindLen Then
 StrCount = StrCount + 1
 Start = Start + FindLen
 End If
 End If
 End If
 Next Start

 End Select
 RtlMoveMemory ByVal TextPtr, TextData, 4
 RtlMoveMemory ByVal TextPtr + 4, 1&, 4
 Else
 FindLen = FindLen + FindLen
 Start = InStrB(Start + FindLen, Text, Find)
 Do While Start
 StrCount = StrCount + 1
 Start = InStrB(Start + FindLen, Text, Find)
 Loop

 End If
 End If
 End If
 Else
 StrCount = StrCount(LCase$(Text), LCase$(Find), Start)
 End If
End Function

MfG Alex

Hi Alex,

Ich weiss nicht ob ich die Function StrCount mit gepostet
habe, die sich dafür anbietet, wenn nicht siehst du sie gleich

)

hast Du, die war gemeint. Steht jetzt auch in der FAQ.

Nein. Wenn die Zeichenketten zwischendurch etwas länger sind,
eventuell ganze Texte, ist Instr() um ein vilefaches
schneller.

Ok, da hast du wiederrum Recht :smile:
Ich habe mal auf die schnelle etwas getippselt. Ich hoffe das
es das ist was du suchst. kannst es mal bei dir laufen lassen
und ne Zeitmessung machen, was schneller ist.

Dafür müssten wir ein File haben, so ist alles zu schnell für eine Messung.

Das Bsp. ist mir nur auf die schnelle eingefallen :wink: und
sicher noch optimierbar :wink: Naja schau es Dir mal an :smile:

Na ja, ich habe ‚gemogelt‘ :smile: Ich ersetze die Klammern erst
durch andere und beim Abarbeiten wieder durch die Richtigen,
dann ergibt sich die richtige Zuordnung von selbst. Das ist
extrem zuverlässig, aber sicher nicht der schnellste Code.

Nein, denn kannst du gewaehrleisten das das Zeichen nicht
schon einmal irgendwo in dem Text da vorkommt ? Für mich waere
das zu heikel und ich würde fein die {} Zeichen suchen :wink:

Ich habe kein Testfile, ich habe mir nur den Beispielstring
mit ein paar Zeichen getippt.

Teste mal bitte meine Variante und mache mal ne Zeitmessung.
Mal schauen um wievieles meines langsamer ist :s

OK, ich teste mal … Ich weiß doch, daß mein Code langsam ist …

Gruß Rainer

Hallo Rainer,

hast Du, die war gemeint. Steht jetzt auch in der FAQ.

Ich schau gleich mal vorbei :wink:

Dafür müssten wir ein File haben, so ist alles zu schnell für
eine Messung.

Kann man sich net einfach nen RTF File besorgen oder halt fix neu erstellen und das auslesen. Das da noch rein zu nageln geht ja fix :smile:

OK, ich teste mal … Ich weiß doch, daß mein Code langsam ist

Naja meiner auch. Wie du siehst arbeite ich mit einem Array und trage da die Daten ein. Man koennte den String auch gleich zusammensetzen aber dient eigentlich nur der Demo :wink:

MfG Alex

Hi Alex,

ich habe noch eine Listbox eingabaut, OK, ist auch noch eine Bremse.

10000 Durchläufe, Dein Code 2 Sekunden, meiner 2,5. :smile:
Die Ergebnisse sind natürlich identisch. Aber ich habe ja auch gar nicht versucht, den Code schnell zu machen. :frowning:

Gruß Rainer

Hi Alex,

leicht verändert, 1,8 Sekunden … ich prüfe aber auch nicht, ob es gleich viele öffnende und schließende Klammern gibt … Ohne ein Originalfile bringt das nichts.

Dafür habe ich ein paar Zeilen Code weniger. :smile:

Private Sub Command2\_Click()
 Dim Satz As String, Pos1 As Integer, Pos2 As Integer, Txt As String
 Dim i As Long, t As Double
 t = Timer
 For i = 1 To 10000
 List1.Clear
 Satz = "Test{a{b{c}{d}}e}"
 Satz = Replace(Satz, "{", "(")
 Satz = Replace(Satz, "}", ")")
 For Pos1 = Len(Satz) - 1 To 1 Step -1
 Pos1 = InStrRev(Satz, "(", Pos1)
 If Pos1 = 0 Then Exit For
 Pos2 = InStr(Pos1, Satz, ")")
 If Pos2 = 0 Then Exit For
 Mid(Satz, Pos1, 1) = "{"
 Mid(Satz, Pos2, 1) = "}"
 List1.AddItem Mid(Satz, Pos1, Pos2 - Pos1 + 1)
 Next
 Next
 Me.Caption = Timer - t
End Sub

Gruß Rainer

Hallo Rainer,

ich habe noch eine Listbox eingabaut, OK, ist auch noch eine
Bremse.

Das stimmt. Dafür habe ich die Anzeige via Debug.print drinnen :wink:

10000 Durchläufe, Dein Code 2 Sekunden, meiner 2,5. :smile:
Die Ergebnisse sind natürlich identisch. Aber ich habe ja auch
gar nicht versucht, den Code schnell zu machen. :frowning:

Du das habe ich auch nicht. Mir ging es erst einmal hauptsaechlich um die Funktion. Sicherlich kann man da auch noch die eine oder andere Sekunde raus kitzeln :smile:

Aber so schön es auch ist, einen kurzen Code zu schreiben Rainer. Kuerzer Code bedeutet nicht gleich das er auch schneller ist. Es gibt da gewisse Feinheiten, wie zum Bsp. LenB etc. die viel bringen :smile:

MfG Alex

Hi Alex,

ich habe noch eine Listbox eingabaut, OK, ist auch noch eine
Bremse.

Das stimmt. Dafür habe ich die Anzeige via Debug.print drinnen
:wink:

auf meinem Computer nicht mehr. *gg* Du schreibst in die Listbox.

10000 Durchläufe, Dein Code 2 Sekunden, meiner 2,5. :smile:
Die Ergebnisse sind natürlich identisch. Aber ich habe ja auch
gar nicht versucht, den Code schnell zu machen. :frowning:

Du das habe ich auch nicht. Mir ging es erst einmal
hauptsaechlich um die Funktion. Sicherlich kann man da auch
noch die eine oder andere Sekunde raus kitzeln :smile:

Aber so schön es auch ist, einen kurzen Code zu schreiben
Rainer. Kuerzer Code bedeutet nicht gleich das er auch
schneller ist. Es gibt da gewisse Feinheiten, wie zum Bsp.
LenB etc. die viel bringen :smile:

Ich weiß, keiner der Codes ist auf Speed getrimmt, etwas langsamerers als Stringmanipulation fällt mir kaum ein. Am WE können wir ja mal feilen. *gg*

Gruß Rainer

Dafür müssten wir ein File haben, so ist alles zu schnell für
eine Messung.

Kann man sich net einfach nen RTF File besorgen oder halt fix
neu erstellen und das auslesen. Das da noch rein zu nageln
geht ja fix :smile:

Hallo Alex, Hallo Rainer,

falls eine rtf-Datei gebraucht wird, vielleicht mal meine Ausgangsfrage lesen da steht sie sogar in fett, der Blink-Tag ist ja hier nicht zugelassen :smile:)

Hier nochma: http://www.badongo.com/file/10494733

Gruß
Reinhard

Hallo Rainer,

auf meinem Computer nicht mehr. *gg* Du schreibst in die
Listbox.

Ok, hast du auch die Prüfung via StrCount drinnen oder haste die auch raus genommen?

Ich weiß, keiner der Codes ist auf Speed getrimmt, etwas
langsamerers als Stringmanipulation fällt mir kaum ein. Am WE
können wir ja mal feilen. *gg*

Da bin ich wahrscheinlich in Berlin Rainer und habe da keine Zeit :s

MfG Alex

Hi Alex,

Ok, hast du auch die Prüfung via StrCount drinnen oder haste
die auch raus genommen?

Die habe ich in Deinem Code gelassen.

Ich weiß, keiner der Codes ist auf Speed getrimmt, etwas
langsamerers als Stringmanipulation fällt mir kaum ein. Am WE
können wir ja mal feilen. *gg*

Da bin ich wahrscheinlich in Berlin Rainer und habe da keine
Zeit :s

Ohhh, grüß mal Berlin von mir. :smile: Ich habe 16 Jahre dicht neben der Schönhauser gewohnt. :smile:

Gruß Rainer

hallo Reinhard,

falls eine rtf-Datei gebraucht wird, vielleicht mal meine
Ausgangsfrage lesen da steht sie sogar in fett, der Blink-Tag
ist ja hier nicht zugelassen :smile:)

sorry. Hab ich vergessen. Wo sagtest Du gibt es die Ginseng-Kapseln?

Hier nochma: http://www.badongo.com/file/10494733

Geladen, mit beiden Codes getestet, identische Ergebnisse. :smile:
Der String wird ordentlich zerlegt.

Gruß Rainer