2011-08-17 15 views
8

Questa domanda è per discutere come codificare un correttore ortografico e non è un duplicato del componente Delphi Spell Checker.Un codice correttore ortografico in Delphi?

Due anni fa, ho trovato e utilizzato il codice del correttore ortografico da Peter Norvig at his website in Python. Ma le prestazioni non sembravano alte. Molto interessante, più lingue che implementano lo stesso compito sono state aggiunte di recente nel suo elenco di pagine web.

Alcune linee di pagina di Peter includono sintassi del tipo:

[a + c + b  for a, b in splits for c in alphabet] 

Come tradurre in Delphi?

Sono interessato a come l'esperto di Delphi in SO utilizzerà la stessa teoria e svolgerà lo stesso compito con alcune linee adatte e prestazioni mediocri o migliori. Questo non significa minimizzare alcun linguaggio, ma imparare a confrontare il modo in cui implementano il compito in modo diverso.

Grazie mille in anticipo.

[Edit]

citerò Marcelo Toledo che contribuisce versione C, come dicendo: "... Mentre lo scopo di questo articolo [Versione C] era quello di mostrare gli algoritmi, non per evidenziare Python ..." . Anche se la sua versione C è la seconda più grande, secondo il suo articolo, la sua versione è ad alte prestazioni quando il file del dizionario è enorme. Quindi questa domanda non mette in evidenza nessuna lingua, ma richiede la soluzione delphi e non è destinata alla competizione, sebbene Peter sia influente nel dirigere Google Research.

[Update]

sono stato illuminato dalla suggerimento di David e studiato teoria e la routine della pagina Peter. È stata eseguita una routine molto approssimativa e inefficiente, leggermente diversa dalle altre lingue, la mia è la GUI. Sono un principiante e uno studente di Delphi, non oso pubblicare il mio codice completo (è scritto male). Illustrerò la mia idea di come l'ho fatto. Il tuo commento è benvenuto in modo che la routine venga migliorata.

Il mio hardware e software è vecchio. Questo è sufficiente per il mio lavoro (la mia specializzazione non è nel computer o programma relativo)

AMD Athlon Dual Core Processor 
2.01 Ghz, 480 Memory 
Windows XP SP2 
IDE Delphi 7.0 

Questa è l'istantanea e il record di tempo di elaborazione della parola 'corretta'. Ho provato Gettickcount, Tdatetime e Queryperformancecounter per tracciare l'ora esatta per parola, ma gettickcount e Tdatetime emetteranno o ms per ogni controllo, quindi devo usare Queryperformancecounter. Forse ci sono altri modi per farlo in modo più preciso.

Le linee totali sono 72, esclusa la funzione che registra l'ora di controllo. Il numero di linee non può essere un metro come sopra indicato da Marcelo. Il post è discutere come fare diversamente il compito. Delphi Experts in SO utilizzerà ovviamente le linee minime per farlo con le migliori prestazioni.

Spell Checker

procedure Tmajorform.FormCreate(Sender: TObject); 
begin 
loaddict; 
end; 

procedure Tmajorform.loaddict; 
var 
fs: TFilestream; 
templist: TStringlist; 
p1: tperlregex; 
w1: string; 
begin 
//load that big.txt (6.3M, is Adventures of Sherlock Holmes) 
//templist.loadfromstream 
//Use Tperlregex to tokenize (I used regular expression by [Jan Goyvaerts][5]) 
//The load and tokenize time is about 7-8 seconds on my machine, Maybe there are other ways to 
//speed up loading and tokenizing. 
end; 

procedure Tmajorform.edits1(str: string); 
var 
i: integer; 
ch: char; 
begin 
// This is to simulate Peter's page in order to fast generate all possible combinations. 
// I do not know how to use set in delphi. I used array. 
// Peter said his routine edits1 would generate 494 elements of 'something'. Mine will 
// generate 469. I do not know why. Before duplicate ignore, mine is over 500. After setting 
// duplicate ignore, there are 469 unique elements for 'something'. 
end; 

procedure Tmajorform.correct(str: string); 
var 
i, j: integer; 
begin 
//This is a loop and binary search to add candidate word into list. 
end; 

procedure Tmajorform.Button2Click(Sender: TObject); 
var 
str: string; 
begin 
// Trigger correct(str: string); 
end; 

Sembra da TFileStream può aumentare il carico corrispondente a 1-2 secondi. Ho provato a utilizzare il metodo CreateFileMapping ma non sono riuscito e mi è sembrato un po 'complicato. Forse ci sono altri modi per caricare velocemente file enormi. Poiché questo big.txt non sarà grande considerando la disponibilità di corpus, ci dovrebbe essere un modo più efficiente di caricare file sempre più grandi.

Un altro punto è che Delphi 7.0 non ha un'espressione regolare incorporata. Ho dato un'occhiata ad altre lingue che eseguono il controllo ortografico nella pagina di Perter, in gran parte chiamano direttamente la loro espressione regolare incorporata. Ovviamente, il vero esperto non ha bisogno di alcuna classe o libreria built-in e può costruire da solo. Per principianti, alcune classi o librerie sono convenienti.

Il tuo commento è benvenuto.

[Update]

ho continuato la ricerca e la funzione di edits2 ulteriormente incluso (edit distance 2). Ciò aumenterà di circa altre 12 righe di codice. Peter ha detto che modificare la distanza 2 includerebbe quasi tutte le possibilità. 'qualcosa' avrà 114.324 possibilità. La mia funzione genererà 102.727 possibilità UNICHE per questo. Naturalmente, le parole suggerite includeranno anche di più.

Se con edit2, il tempo di risposta per la correzione si riduce ovviamente in quanto aumenta i dati di circa 200 volte. Ma trovo che alcune correzioni suggerite siano ovviamente impossibili dato che un dattilografo non scriverà una parola di errore che sarà nella lunga lista di parole corrette. Pertanto, la modifica della distanza 1 sarà migliore a condizione che il file big.txt sia sufficientemente grande da includere più parole corrette.

Di seguito è riportata l'istantanea del rilevamento delle modifiche 2 volta corretta.

enter image description here

+2

Vuoi da noi implementarlo in Delphi e dirti quante linee e come sono state le prestazioni? Sembra più una competizione che una domanda seria. Ad ogni modo non possiamo misurare i risultati su macchine diverse e confrontarle con quelle di Peter Norvig. -1 almeno fino a quando non spieghi cosa vuoi veramente sapere. –

+0

@daemon_x, voglio sapere come farlo in Delphi. Come tradurre la sintassi python nella pagina di Peter come "[(word [: i], word [i:]) per i in range (len (word) + 1)]" o "[a + c + b [1: ] per a, b in split per c in alfabeto if b] ". Il fatto che Peter elenchi le lingue per il compito non significa concorrenza ma suggerisce che più di una lingua può farlo. Non ho provato tutte le versioni linguistiche. Sebbene alcune lingue siano etichettate con meno righe, potrebbero non significare prestazioni migliori. – Dylan

+0

@ user482742 - -1 rimosso; potrebbe essere molto interessante tradurre il codice in Delphi, ma non è una buona domanda (attività) per SO. –

risposta

8

Questa è una lista Python comprensione. Forma il prodotto cartesiano di croste e alfabeti.

Ogni elemento di suddivisione è una tupla che viene decompressa in a e b. Ogni elemento di alfabeto è inserito in una variabile chiamata c. Quindi le 3 variabili sono concatenate, assumendo che siano stringhe. Il risultato dell'espressione di comprensione delle liste è una lista contenente elementi della forma a + c + b, un elemento per ogni articolo nel prodotto cartesiano.

In Python si potrebbe scrivere equivalentemente come

res = [] 
for a, b in splits: 
    for c in alphabets: 
    res.append(a + c + b) 

In Delphi sarebbe

res := TStringList.Create; 
for split in splits do 
    for c in alphabets do 
    res.Add(split.a + c + split.b); 

vi consiglio di leggere su Python list comprehensions per ottenere una migliore comprensione di questo molto potente funzione Python.

Problemi correlati