Zeichen aus einem String entfernen [ERLEDIGT]

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo Manfred,

zuerst einmal möchte ich mich bedanken, dass du mir die Augen über die zusätzlichen Parameter von StrTran() geöffnet hast, die hatte ich doch all die Jahre übersehen ... :!:

Dann möchte ich dir vorschlagen mit einfachen Worten zu Erklären welche Zeichen du wo (am Anfang ... wie lang ?) entfernen möchtest.
Mit der Erklärung könnte man sich dann über eine Lösung Gedanken machen. Der Code ist ehrlich gesagt etwas komplex und ohne zu Wissen was du wirklich willst schwer zu beurteilen :wink:
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Hubert,
ein Beispiel hat er ja schon gebracht - aber die zusätzlichen Parameter bei strtran() bringen ihm dabei nichts, da ja auch bei Angabe der 1 als Anzahl der zu ersetzenden Vorkommen das Zeichen am Ende des Stringes stehen könnte...
So wie ich ihn verstanden habe, will er immer nur das erste Zeichen ersetzen, wodurch die restlichen nach links rutschen (also das zweite jetzt das erste ist).
Danach muss er erneut von vorne prüfen, da ja das neue erste Zeichen wieder ein "verbotenes" sein könnte.
Danach muss er auch die Silben entfernen, wobei die natürlich nicht an erster Stelle, sondern an den ersten vier Stellen (also auch hier am Anfang) stehen können (wohlgemerkt: bei einer Länge von drei Zeichen plus Leerzeichen).
Danach müssen auch wieder die restlichen Kombinationen geprüft werden, da ja das jetzt erste Zeichen (das eben noch an fünfter Stelle stand) wieder ein "verbotenes" sein könnte.
Ist eigentlich in meinen Augen (wenn ich das oben so richtig wiedergegeben habe) optimal für eine Lösung per Rekursion - oder wie siehst Du das, Hubert?

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo Manfred,

ein Problem von Xbase++ sind die langsamen Schleifendurchläufe.
Je weniger Prüfungen du durchführst, je schneller wird das Programm.

Angenommen du möchtest immer das erste Zeichen prüfen ob es gesperrt ist und auch führende Blanks entfernen, ist diese Vorgehensweise bestimmt sehr schnell, da nicht jedes gesperrte Zeichen mit dem String verglichen wird, sondern das erste des Strings (1 Vergleich !) und danach gleich noch alle führenden Blanks entfernt werden (spart eventuell mehrere Prüfungen ...)

Code: Alles auswählen

cBlockZeichen := ")(! §$%&/?\´`'#"+chr(34) // das " auch noch ?
cTxt := "\    Test"

? RemoveLeftChar(cTxt,cBlockZeichen,.t.) // Länge auffüllen

function RemoveLeftChar(cTxt,cBlockZeichen, lFill)
    local nLen := len(cTxt)
    do while len(cTxt)>0 .and. left(cTxt,1) $ cBlockZeichen
         // das erste Zeichen ist unerwünscht ...
         cTxt := alltrim(substr(cTxt,2))
    enddo
    if lFill
       cTxt := left(cTxt + space(nLen),nLen)
    endif
return cTxt
In dem Beispiel wird die Funktion genau einen Durchlauf brauchen.
Wenn du dann noch "DIE" "DAS" etc. entfernen willst, kannst du aus dieser eine neue Funktion machen, die variable Zeichenkettenlängen von links her vergleicht, wobei die Sperrwörter immer gleich lang sein müssen, sonst kann man nicht sicher sein das falsche zu erwischen.
Auch muss man aufpassen nur nach DIE zu suchen, sonst erwischt man auch einen "Dienstag ..." ...
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Martin Altmann hat geschrieben:ein Beispiel hat er ja schon gebracht - aber die zusätzlichen Parameter bei strtran() bringen ihm dabei nichts
wiedereinmal überschneiden sich unsere Mails ;-)

das Beispiel weiter oben hatte ich beim ersten Überblick übersehen und mir dann meine obige Bedingung überlegt, ob sie stimmt weiß ich nicht.
Die zusätzlichen Parameter von StrTran() kann er nicht brauchen, aber vielleicht ich einmal und deshalb habe ich mich bedankt. Mir waren die noch nicht aufgefallen.
Martin Altmann hat geschrieben:Danach muss er auch die Silben entfernen
das hatte ich jetzt nicht so verstanden, welche Silben auch ?

Also muss er doch besser erklären, was er genau will.
Ich dachte nach dem ersten erlaubten Zeichen ist Schluss...
Martin Altmann hat geschrieben:Ist eigentlich in meinen Augen (wenn ich das oben so richtig wiedergegeben habe) optimal für eine Lösung per Rekursion - oder wie siehst Du das, Hubert?
Solange er nur ein Zeichen entfernen will reicht die Funktion.
Wenn es komplexer wird ist eine rekursive Funktion sichern nicht schlecht, wobei der schnelle Vergleich (ein Aufruf prüft alle gesperrten Zeichen auf einmal) immer erzwingt, dass die Länge der Suchzeichenkette gleich mit den Blocks im Vergleichsstring ist und durch eine bekannten Worttrenner abgetrennt ist (sonst können Wortbestandteile ungewollt passen):

z.B.
upper(left(cTxt,4)) $ "DER DIE DAS " etc.
upper(left(cTxt,3)) $ "DA DU DO " etc.

aber übel wird es, wenn man "DER DER,DER!DER/DER(DER)" etc.
suchen muss, dann braucht man einen richtigen Parser ...
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Hubert,
mit Silben meinte ich genau Dein Beispiel "DER DIE DAS THA " usw.
Rekursion ist eigentlich einfach:
Man prüft einfach immer nur das erste Zeichen, ob es in Deiner Liste mit den einzelnen Zeichen drin ist. Wenn ja, gibt man den Rest des Strings (also ab der zweiten Stelle) als Parameter an die selbe Funktion - beim Zurückkommen aus dieser hängt man ein Leerzeichen an.
Wenn das erste Zeichen kein verbotenes ist, prüft man, ob die ersten vier Zeichen in den verbotenen Dreier-Silben (plus Leerzeichen) vorkommen - wenn ja, ruft man die Funktion mit dem Rest des Strings (also ab der fünften Stelle) auf und hängt beim Zurückkommen vier Leerzeichen an.
Ist auch das nicht der Fall, gibt man den String unverändert zurück - die Rekursion ist beendet.
Beispiel:

Code: Alles auswählen

function RemoveLeftChar(cTxt)
local cBlockZeichen := ")(! §$%&/?\´`'#"+chr(34)
local cBlockSilben := "DER DIE DAS THA "
local cText
if left( cTxt, 1 ) $ cBlockZeichen
   cText := RemoveLeftChar( substr( cTxt, 2, ) ) + " "
elseif left( cTxt, 4 ) $ cBlockSilben
   cText := RemoveLeftChar( substr( cTxt, 5, ) ) + space( 4 )
else
   cText := cTxt
endif
return cText
Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi Martin,

ich weiß schon was eine Rekursion ist und nutze diese in meiner Funktion zum Löschen von Verzeichnisbäumen mit Dateien auch fleisig.

Im Beispiel mit genau einem Zeichen von vorne, ist aber eine Funktion ohne Rekursion (wie meine oben) schneller, da eine Schleife und lokale Variablen dem Rechner weniger Arbeit machen, als der rekursive Start einer Funktion, die ja alles Mögliche auf den Stack räumen und wieder abräumen muss.

Wenn die Funktion flexibler sein muss überwiegt sicher der einfacherere Aufbau der rekursiven Funktion gegenüber eventuellen Geschwindigkeitsüberlegungen.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Wobei du bei deiner Funktion übersehen hast (ja das Cut & Paste ;-) ) dass ein Blank bei den gesperrten Zeichen enthalten ist.
Führende Blanks sollten ja auch entfernt werden.
Deshalb darf man hinten den String nicht um Blanks verlängern, sonst kommt man in eine Endlosschleife.

Ansonsten kann Manfred deine Funktion aber leicht um weitere Sperrungen erweitern und muss den Längenausgleich halt nach dem Aufruf der Funktion in seinem Programm machen.

PS:

hat es einen Grund, dass du local cText als Ziel nutzt und nicht die cTxt aus dem Parameter ?
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Hubert,
Endlosschleife ist nicht - Du hast übersehen, dass die Blanks erst beim Zurückkommen aus der Funktion angehangen werden - jaja, die gute Rekursion... :D
Einen wirklichen Grund (cText) hat es nicht - ausser, dass ich Probleme (Überlagerung) vermeiden will...

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Martin Altmann hat geschrieben:Hallo Hubert,
Endlosschleife ist nicht - Du hast übersehen, dass die Blanks erst beim Zurückkommen aus der Funktion angehangen werden - jaja, die gute Rekursion... :D
wo DU recht hast hast du Recht ... das war meine Bauchlandung ... ich habe heute eindeutig zu weinig Kaffee getrunken.
Das hole ich gleich nach ... :D
Martin Altmann hat geschrieben:Einen wirklichen Grund (cText) hat es nicht - ausser, dass ich Probleme (Überlagerung) vermeiden will...
welche Überlagerungen ?

Der übergebene Parameter ist doch auch eine LOCAL und somit geschützt solange man keine Referenz übergibt ... oder übersehe ich wieder was. :)
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Hubert,
wir unterhalten hier heute das ganze Forum alleine, wa? :lol:
Nun, Überlagerung nicht im eigentlichen Sinne, da hast Du Recht!
Aber ich persönlich finde es übersichtlicher, für die Rückgabe eine neue Variable zu nehmen...
Klar geht cText := strtran( left( cText, int( len( cText ) / 2 ) ), "ä", "ae" ) - aber ich habe bei sowas immer (optische) Bauchschmerzen. Das ist immer so (vom Gefühl her), als ob man jemandem dem Stuhl unter dem Hintern wegzieht, wenn Du verstehst, wie ich das meine...

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Martin Altmann hat geschrieben:Das ist immer so (vom Gefühl her), als ob man jemandem dem Stuhl unter dem Hintern wegzieht, wenn Du verstehst, wie ich das meine...
jedem das Seine ;-)

ich mag z.B. ELSEIF nicht und nehme in Xbase++ immer DO CASE, auch wenn ich Beispiele übernehme wird das umgewandelt ;-)
Gruß
Hubert
Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2936
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Hat sich bedankt: 13 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Beitrag von Wolfgang Ciriack »

Wär es da nicht einfacher, das Entfernen der nicht gewünschten Zeichen einmalig beim Anlegen oder Ändern des Artikels vorzunehmen und dieses dann in ein zusätzliches Datenbankfeld aufzunehmen ?
Damit spart man sich doch eine Menge Zeit und Nerven :D
Viele Grüße
Wolfgang
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

nach Wolfgangs Message habe ich mal den Anfang des 3 seitigen Threads angelesen ... die Vorgeschichte hatte ich total vergessen ... und kann Wolfgang nur zustimmen, solange du linksbündig suchen bzw. sortiert haben willst.

Eine zusätzliche Möglichkeit wäre eine freie Suche (Volltext) mit OrdWildSeek():

zuerst alle gültigen Datensätze suchen und die Recno() in ein Array speichern,
dann für die Browseanzeige dieses Array zur Satzauswahl der Anzeige nutzen.

Anders - vor allem in einem Browser - rechnet sich das Programm ja dumm und dämlich bei jeder Satzbewegung.
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi ihr Alleinunterhalter,

brrrrr, gelesen habe ich jetzt alles, aber verwirrt bin ich total. Jetzt werde ich mir erstmal den Kopf gerade drehen und noch etwas probieren.

Bis später
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Das ist ja jetzt sehr interessant für mich:

Code: Alles auswählen

*
*
*
*
* Letzte Änderung:25.11.2007
********************************************************************************
* indexohneartikel.prg   Tempotest
********************************************************************************
PROCEDURE main()
          LOCAL cAnfang
          LOCAL cEnde

          PRIVATE bTitel := {|| indexohne(Upper(FIELD->bez)) }

          CLS
          DbUseArea(.T.,,"titel")
          cAnfang := TIME()
          titel->(OrdCreate("titel",,"eval(bTitel)"))
          cEnde   := TIME()
          altd()
          titel->(DbGoTop())
          browse()
          RETURN
********************************************************************************
FUNCTION indexohne(cIndexKey)
         LOCAL aZeichen := {;
                            {")",1},;
                            {"(",1},;
                            {"!",1},;
                            {" ",1},;
                            {"§",1},;
                            {"$",1},;
                            {"%",1},;
                            {"&",1},;
                            {"/",1},;
                            {"?",1},;
                            {"\",1},;
                            {"´",1},;
                            {"`",1},;
                            {"'",1},;
                            {"-",1},;
                            {"_",1},;
                            {"#",1};
                           }
         LOCAL cIndexKey2 := cIndexKey
         LOCAL lFertig    := .F.
         LOCAL nIndexOrgLaenge := LEN(cIndexKey)      // wird nachher für die evtl. fehlenden Zeichen benötigt
         LOCAL nIndexNeuLaenge

/*         DO WHILE ! lFertig
            lFertig := .T.
            IF EMPTY(cIndexKey)     // das kann auch vorkommen
               EXIT                                                               // es würde sonst arg lange dauern
            ENDIF
            Aeval(aZeichen, {|x,nI| IF(CountLeft(cIndexKey,aZeichen[nI,1]) > 0,cIndexKey := StrTran(cIndexKey,aZeichen[nI,1],,1,aZeichen[nI,2]),NIL)})
            nIndexNeuLaenge := Len(cIndexKey)
            IF nIndexOrgLaenge <> nIndexNeuLaenge
               cIndexKey +=  + SPACE(nIndexOrgLaenge - nIndexNeuLaenge)
               lFertig := .F.
            ENDIF
         ENDDO */
         RETURN cIndexkey
Nur der Aufruf der Funktion, die sofort mit einem RETURN cIndexKey zurückkommt, dauert es genau so lange (13 Sekunden) wie ohne Funktion im Index. Wenn ich aber nur die reinen Local Vars deklariere und das Array belege und dann sofort zurückschicke, dann dauert es schon 26 Sekunden.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Auch auf die Gefahr hin, dass ich jetzt nerve,

aber wenn ich das Array aZeichen aus der Funktion entferne und das Array direkt in main() deklariere und dann per Parameter übergebe, dann komm ich von 58 Sekunden auf 46 Sekunden Laufzeit. Nachvollziehbar, aber das es so gravierend sein kann.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Manfred,
ich vermute mal, wenn Du das Array public deklarierst und gar nicht übergibst, wird es noch ein wenig schneller.

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Martin,

nein, statt 46 sind es dann 51 Sekunden.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14655
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Beitrag von Jan »

Off topic: Martin, nimm das andere Bild wieder! Das jetzige sieht ja aus wie ein Fahndungsfoto.

Jan
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Aha!
Bei wieviel Datensätzen?
Ist das jetzt insgesamt schneller als vorher (ich meine jetzt die 46 Sekunden) oder nicht?
Wie sieht denn Deine Funktion nun aus - so wie von mir vorgeschlagen mit Rekursion (dann müsste es schneller sein, das Array public zu deklarieren statt local in der Funktion)?
Oder so wie vor vier Postings?

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Ne jan,

nicht Off Toppic. Du hast vollkommen Recht.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Ist ja auch eines - für unsere neuen Betriebsausweise :D
Da erkennt man mich dann wenigstens besser...

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Martin,

so, läuft es 46 Sekunden bei ca 536000 Sätzen

Code: Alles auswählen

PROCEDURE main()
         LOCAL aZeichen := {;
                   {")",1},;
                   {"(",1},;
                   {"!",1},;
                   {" ",1},;
                   {"§",1},;
                   {"$",1},;
                   {"%",1},;
                   {"&",1},;
                   {"/",1},;
                   {"?",1},;
                   {"\",1},;
                   {"´",1},;
                   {"`",1},;
                   {"'",1},;
                   {"-",1},;
                   {"_",1},;
                   {"#",1};
                  }
          LOCAL cAnfang
          LOCAL cEnde

          PRIVATE bTitel := {|| indexohne(Upper(FIELD->bez),aZeichen) }

          CLS
          DbUseArea(.T.,,"titel")
          cAnfang := TIME()
          titel->(OrdCreate("titel",,"eval(bTitel)"))
          cEnde   := TIME()
          altd()
          titel->(DbGoTop())
          browse()
          RETURN
********************************************************************************
FUNCTION indexohne(cIndexKey,aZeichen)
         LOCAL cIndexKey2 := cIndexKey
         LOCAL lFertig    := .F.
         LOCAL nIndexOrgLaenge := LEN(cIndexKey)
         LOCAL nIndexNeuLaenge

         DO WHILE ! lFertig
            lFertig := .T.
            IF EMPTY(cIndexKey)                                                   // das kann auch vorkommen
               EXIT                                                               // es würde sonst arg lange dauern
            ENDIF
            Aeval(aZeichen, {|x,nI| IF(CountLeft(cIndexKey,aZeichen[nI,1]) > 0,cIndexKey := StrTran(cIndexKey,aZeichen[nI,1],,1,aZeichen[nI,2]),NIL)})
            nIndexNeuLaenge := Len(cIndexKey)
            IF nIndexOrgLaenge <> nIndexNeuLaenge
               cIndexKey +=  + SPACE(nIndexOrgLaenge - nIndexNeuLaenge)
               lFertig := .F.
            ENDIF
         ENDDO
         RETURN cIndexkey
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Martin,

durch diese weiße blasse Farbe im Gesicht wirkst Du nicht gerade gesund.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Manfred,
das ist die vornehme Blässe :D Wurde halt ein wenig überbelichtet, damit es besser erkennbar ist...
Probier' das doch mal mit der Rekursion statt Deines AEval()s...

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Antworten