Freitag, 7. Oktober 2011

Stringinvertierung - andersherum / inverting strings - the other way around

Beim durchstöbern meiner Codeschnipsel stolperte ich eben über eine andere Sichtweise der Stringinvertierung. Bei dieser geht es um einen einfachen Positionstausch innerhalb eines übergebenen Strings.

Mit anderen Worten: aus
 MeineInvertierteZeichenkette
wird
etteknehcieZetreitrevnIenieM
Das folgende Codemuster zeigt drei mögliche Wege auf, dies zu erreichen...

* // Funktionstest 
CLEAR 
liS=SECONDS()
?RevertString1( [etteknehcieZetreitrevnIenieM] )
?SECONDS() - liS

liS=SECONDS()
?RevertString2( [etteknehcieZetreitrevnIenieM] )
?SECONDS() - liS

liS=SECONDS()
?RevertString3( [etteknehcieZetreitrevnIenieM] )
?SECONDS() - liS

* Invertieren mit VFP Bordmitteln                        
FUNCTION RevertString1
LPARAMETERS vString AS String
    LOCAL liZaehler AS Integer, lcReturn AS String
    liZaehler    = 0
    lcReturn    = []
    FOR liZaehler = LEN ( vString ) TO 1 STEP -1
        lcReturn = lcReturn + SUBSTR ( vString , liZaehler , 1 )
    ENDFOR
    RETURN lcReturn
ENDFUNC

* Invertieren über die MS C++ Laufzeitbibliothek        
FUNCTION RevertString2
LPARAMETERS vString as String
    DECLARE STRING _strrev IN msvcrt20.dll STRING @
    m.vString = m.vString + CHR( 0 )
    RETURN _strrev( @m.vString )
ENDFUNC 

* Invertieren mit Bordmitteln und optimierter Schleife    
FUNCTION RevertString3
LPARAMETERS vString AS String
    LOCAL lcReturn as String
    lcReturn = SPACE( LEN( vString ) )
    FOR liZaehler = 1 TO LEN( vString ) / 2
        lcReturn = STUFF( lcReturn , liZaehler , 1 , SUBSTR( vString , LEN( vString ) + 1 - liZaehler , 1) )
        lcReturn = STUFF( lcReturn , LEN( vString ) + 1 - liZaehler , 1 , SUBSTR( vString , liZaehler , 1) )
    ENDFOR 
    RETURN lcReturn
ENDFUNC 

Bei kleinen Strings ist der zeitliche Unterschied marginal. Bei größeren Textmengen sieht es aber ganz anders aus und die Schere zu Variante 1 geht immer weiter auseinander.

2 Kommentare:

  1. Hello TOm !
    Thanks for sharing, this post has been very useful to me.
    I did some tests, and the 2nd procedure, using the msvcrt20.dll is the best option. The others are faster if you need to DECLARE the C++ function every time. But if you need to repeat many times the string inversion, it becomes up to 7 times faster !
    This brought a significant performance enhancement. This will be used in FoxyPreviewer, for languages that are written from Right to left.
    Cheers
    Cesar

    AntwortenLöschen
  2. Hi Cesar,
    thanks for your comment.
    Indeed declaring the function each time it is needed reduces its speed. In such a case it makes a lot more sense, to declare it once and keep it available.
    I am glad that this post it of value for one of your community projects.

    -Tom

    AntwortenLöschen