AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Schneller Stringvergleich nach bestimmtem Muster

Ein Thema von taveuni · begonnen am 9. Dez 2015 · letzter Beitrag vom 14. Dez 2015
Antwort Antwort
Seite 1 von 3  1 23      
taveuni

Registriert seit: 3. Apr 2007
Ort: Zürich
526 Beiträge
 
Delphi 11 Alexandria
 
#1

Schneller Stringvergleich nach bestimmtem Muster

  Alt 9. Dez 2015, 10:05
Hallo zusammen,
Der Titel ist etwas bescheuert - mir ist aber nichts besseres eingefallen. Folgendes Szenario: Es werden automatisch irgendwelche Codes gescannt an verschiedenen Stellen - nennen wir diese Eingänge. Die Artikel werden befördert und kommen an Ausgänge an welchen sie wieder gescannt werden. Nun sollen Artikel welche an bestimmten Eingängen eingegangen sind automatisch an bestimmten Ausgängen gesondert behandelt werden. Soweit einfach - wir erhalten die Standorte sowie die Scancodes. Die Codes der definierten Eingänge sammeln wir in einem Pool. Wenn wir an einem Ausgang einen Code erhalten welcher im Pool ist reagieren wir entsprechend. Das Problem ist nun: Die Codes sind auf teilweise zerknittertem Papier aufgedruckt und werden teilweise unterschiedlich am Ein- und Ausgang gelesen. Alle Versuche seitens des Betreibers diese Fälle zu eliminieren sind gescheitert. Deshalb müssen wir neu wenn wir keinen Match haben auch noch nach einem bestimmten Muster suchen. Wenn dieses zutrifft wird angenommen dass es sich um den identischen (aber unterschiedlich gelesenen) Code handelt. Ich habe mir eine Funktion zusammengeschustert welche funktioniert. Allerdings: Wir erhalten im Durchschnitt 10000 Scans pro Minute. Im Pool können bis zu 30000 Codes sein. Ich muss diesen Vergleich so schnell wie möglich machen. Kann man die Funktion bezüglich Geschwindigkeit optimieren? Folgend ein Beispiel:

Eingangs-Scan: XX123456

Wahrheitstabelle Ausgangs-Scan:

GelesenGültig
XY123456Ja
X123456Ja
XX1234567Ja
Y123456Nein
XX1234Nein

Die bisherige Funktion:
Delphi-Quellcode:
function MatchRule(const BaseStr: String; const CompareList: TStringList): Boolean;
var
  i,j, cntForward, cntBackward: Integer;
  lBase, lComp: Integer;
  StrBase, StrCompare: String;
begin
  Result:= False;
  lBase:= Length(BaseStr);
  for i := 0 to CompareList.Count -1 do
  begin
    lComp:= Length(CompareList[i]);
    if InRange(lBase - lComp,-1,1) then
    begin
      cntForward:= 0;
      cntBackward:= 0;
      if lBase <= lComp then
      begin
        StrBase:= BaseStr;
        StrCompare:= CompareList[i];
      end
      else
      begin
        StrBase:= CompareList[i];
        StrCompare:= BaseStr;
      end;

      // compare contains base
      if Length(StrBase) < Length(StrCompare) then
        Result:= Pos(StrBase, StrCompare) > 0;

      if not Result then
      begin
        // check forward
        for j := 1 to Length(StrBase) -1 do
        begin
          if StrBase[j] = StrCompare[j] then
            inc(cntForward)
          else break;
        end;

        // check backward
        for j := Length(StrBase) downto 1 do
        begin
          if StrBase[j] = StrCompare[j+(Length(StrCompare) - Length(StrBase))] then
            inc(cntBackward)
          else break;


        if lBase = lComp then
          Result:= (cntForward + cntBackward) >= (Length(StrBase) -1)
        else
          Result:= (cntForward + cntBackward) = Length(StrBase);
        end;

      end;
      if Result then Exit;
    end
    else Continue;

  end;
end;
Die Codes können 3-12 stellig sein und beginnen meistens mit Buchstaben.

Die Ansätze welche ich mir zur Verbesserung überlegt habe:
- Sollte ich die Liste zuerst nach dem Anfang des zu prüfenden Strings sortieren?
- Sollten die Längen des Strings zuerst in Variablen gespeichert werden um das dauernde Length() zu vermeiden?
- What else?

Danke für Eure Hilfe
Die obige Aussage repräsentiert meine persönliche Meinung.
Diese erhebt keinen Anspruch auf Objektivität oder Richtigkeit.
  Mit Zitat antworten Zitat
Benutzerbild von baumina
baumina

Registriert seit: 5. Mai 2008
Ort: Oberschwaben
1.275 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Schneller Stringvergleich nach bestimmtem Muster

  Alt 9. Dez 2015, 10:16
Welche Art von Barcodes verwendet ihr denn dass die unterschiedliche Ergebnisse beim scannen liefern können? Klingt ja beängstigend.
Hinter dir gehts abwärts und vor dir steil bergauf ! (Wolfgang Ambros)
  Mit Zitat antworten Zitat
taveuni

Registriert seit: 3. Apr 2007
Ort: Zürich
526 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Schneller Stringvergleich nach bestimmtem Muster

  Alt 9. Dez 2015, 10:19
Es sind keine Barcodes. Es handelt sich um Klartext Charakter. Je nach Land mit unterschiedlichen Fonts usw. Die Erkennung wird via Bildanalyse gemacht. Jede Kamera bringt 250 Bilder/Sek und hat einen eigenen Rechner für die Recognition. Es ist nichts triviales und es kann nicht anders gelöst werden. Deshalb wenn jemand helfen kann zur Verbesserung der Funktion bin ich happy. Die darunterliegende Struktur ist gegeben.
Die obige Aussage repräsentiert meine persönliche Meinung.
Diese erhebt keinen Anspruch auf Objektivität oder Richtigkeit.

Geändert von taveuni ( 9. Dez 2015 um 10:25 Uhr) Grund: Art der Codes ergänzt
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Schneller Stringvergleich nach bestimmtem Muster

  Alt 9. Dez 2015, 10:34
Gibt es noch eine Möglichkeit auf die Code-Gestaltung Einfluß zu nehmen?

Dann wäre es ratsam eine Prüfziffer in die Codes zu integrieren (oder gibt es die schon?) um die falsch gelesenen Codes zu minimieren.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#5

AW: Schneller Stringvergleich nach bestimmtem Muster

  Alt 9. Dez 2015, 10:37
Ich finde das ähnlich gruselig wie Baumina.
Aber was mir spontan zu Deinem Problem einfällt ist die Levenshtein-Distanz
https://de.wikipedia.org/wiki/Levenshtein-Distanz

Kurz, der Algo bestimmt die Anzahl der Unterschiede (Buchstabenänderungen), die bis zur Identität von 2 Worten durchgeführt werden müssen.
Es dürfte vermutlich sogar fertige Implementierungen dazu geben.

Achso vergessen: Man würde dann lediglich die Distanz als Schwellwert definieren und sagen 1 oder 2(das ist schon viel) Schritte wären noch ok. Der Rest ist ungültig.
Gruß, Jo

Geändert von jobo ( 9. Dez 2015 um 10:45 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#6

AW: Schneller Stringvergleich nach bestimmtem Muster

  Alt 9. Dez 2015, 10:44
Deine Vergleichsfunktion ist etwas gewöhnungsbedürftig. Ich hab die mal nachvollzogen

Code:
Return false wenn Längenunterschied größer als 1
Return true wenn kürzerer String in längerem enthalten ist

Zähle wieviel Buchstaben identisch sind, wenn man das kürzere Wort mit dem Anfang des längerem vergleicht
Zähle wieviel Buchstaben identisch sind, wenn man das kürzere Wort mit dem Ende des längerem Vergleicht
Addiere diese Werte
Vergleiche diesen Wert der Länge des kürzerem String
Ist das korrekt?

Was die Überlegung dahinter?
Hast du mal die Levenstein-Distanz getestet? Wie schneidet die im Vergleich ab?
Mit einer Distanz/Metrik kanst du dir eventuell die Dreiecksfunktion zunutze machen um einen Index zu erstellen.
  Mit Zitat antworten Zitat
taveuni

Registriert seit: 3. Apr 2007
Ort: Zürich
526 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Schneller Stringvergleich nach bestimmtem Muster

  Alt 9. Dez 2015, 10:46
Gibt es noch eine Möglichkeit auf die Code-Gestaltung Einfluß zu nehmen?

Dann wäre es ratsam eine Prüfziffer in die Codes zu integrieren (oder gibt es die schon?) um die falsch gelesenen Codes zu minimieren.
Leider nein. Vergleiche es mit Kennzeichen an Fahrzeugen welche Du an Ein- und Ausfahrten via Bild OCR erkennst. Diese können bei der Einfahrt mit Schnee bedeckt, verschmutzt oder sonst was sein. An der Ein- und Ausfahrt können die Lesewinkel, die Beleuchtung usw. unterschiedlich sein. Alle diese Fälle sind unter 2% aber sie sind vorhanden.
Die obige Aussage repräsentiert meine persönliche Meinung.
Diese erhebt keinen Anspruch auf Objektivität oder Richtigkeit.
  Mit Zitat antworten Zitat
taveuni

Registriert seit: 3. Apr 2007
Ort: Zürich
526 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Schneller Stringvergleich nach bestimmtem Muster

  Alt 9. Dez 2015, 10:53

Code:
Return false wenn Längenunterschied größer als 1
Return true wenn kürzerer String in längerem enthalten ist

Zähle wieviel Buchstaben identisch sind, wenn man das kürzere Wort mit dem Anfang des längerem vergleicht
Zähle wieviel Buchstaben identisch sind, wenn man das kürzere Wort mit dem Ende des längerem Vergleicht
Addiere diese Werte
Vergleiche diesen Wert der Länge des kürzerem String
Ist das korrekt?
Richtig. Mit der Ergänzung dass am Schluss beim Vergleich der Werte True ist wenn
- beide Strings gleich lang sind UND der Wert diesem entspricht.
- Der eine kürzer ist und der Wert dem des kürzeren entspricht.

Was die Überlegung dahinter?
Es darf ein Zeichen fehlen, eines falsch sein, eines mehr sein usw. Die Matrix entspricht genau der Realität (dieses Ganzen).

Hast du mal die Levenstein-Distanz getestet? Wie schneidet die im Vergleich ab?
Mit einer Distanz/Metrik kanst du dir eventuell die Dreiecksfunktion zunutze machen um einen Index zu erstellen.
Ja - ich habe alle bekannten Ähnlichkeits Algorithmen getestet. Soundex usw. Diese sind hier nicht anwendbar. Siehe oben.
Die obige Aussage repräsentiert meine persönliche Meinung.
Diese erhebt keinen Anspruch auf Objektivität oder Richtigkeit.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.337 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Schneller Stringvergleich nach bestimmtem Muster

  Alt 9. Dez 2015, 11:19
Also alles <> 100% Übereinstimmung wäre mir mulmig.
In dem Fall würde ich einen Bearbeiter den Treffer erst bestätigen lassen.
Sonst sind falsche Abläufe ja quasi vorprogrammiert.

Aber Du bist mit Deinem Algorithmus zufrieden - lediglich nicht mit der Performance?
Dann kann ich erst mal nicht helfen.

Wir hatten mal einen Thread, der unscharfe Suchen vergleicht: http://www.delphipraxis.net/154811-v...rozentual.html
Ich denke aber eigentlich nicht, dass Dir da etwas weiter hilft.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#10

AW: Schneller Stringvergleich nach bestimmtem Muster

  Alt 9. Dez 2015, 11:30
Es darf ein Zeichen fehlen, eines falsch sein, eines mehr sein usw. Die Matrix entspricht genau der Realität (dieses Ganzen).
Das ist doch Levenshtein Distanz 1 oder (bis auf das usw.)?
Gruß, Jo
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:33 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz