- Soluzione 1:
lascia pensare di questi pezzi nella tua frase come perline su un abaco, con ogni perla costituita da una stringa parziale, le perline può essere spostato a sinistra oa destra per generare le permutazioni. La posizione di ciascun frammento è fissata tra due frammenti adiacenti. Nel caso attuale, le perle sarebbe:
(more)(recen)(t)(ly)(the)(develop)(ment,)(wh)(ich)(is)(a)(po)(ten)(t)
Questo risolve 2 sottoproblemi:
a) branello è una singola unità, in modo da non si preoccupano permutazioni nei tallone cioè permutazioni di "altri" non sono possibili
b) L'ordine delle perline è costante, cambia solo la spaziatura tra di esse. cioè "più" sarà sempre prima di "recen" e così via.
Ora, generare tutte le permutazioni di queste perle, che darà un output simile:
morerecentlythedevelopment,which is a potent
morerecentlythedevelopment,which is a poten t
morerecentlythedevelop ment, wh ich is a po tent
morerecentlythedevelop ment, wh ich is a po ten t
morerecentlythe development,whichisapotent
Poi segnare queste permutazioni in base a quante parole dal dizionario rilevanti contengono, risultati più corretti possono essere facilmente filtrati su. more recently the development, which is a potent
segnerà superiore morerecentlythedevelop ment, wh ich is a po ten t
codice che fa la parte di permutazione delle perline:
import re
def gen_abacus_perms(frags):
if len(frags) == 0:
return []
if len(frags) == 1:
return [frags[0]]
prefix_1 = "{0}{1}".format(frags[0],frags[1])
prefix_2 = "{0} {1}".format(frags[0],frags[1])
if len(frags) == 2:
nres = [prefix_1,prefix_2]
return nres
rem_perms = gen_abacus_perms(frags[2:])
res = ["{0}{1}".format(prefix_1, x) for x in rem_perms] + ["{0} {1}".format(prefix_1, x) for x in rem_perms] + \
["{0}{1}".format(prefix_2, x) for x in rem_perms] + ["{0} {1}".format(prefix_2 , x) for x in rem_perms]
return res
broken = "more recen t ly the develop ment, wh ich is a po ten t"
frags = re.split("\s+",broken)
perms = gen_abacus_perms(frags)
print("\n".join(perms))
demo: http://ideone.com/pt4PSt
- Soluzione # 2 :
Suggerirei un approccio alternativo che utilizza l'analisi dell'analisi del testo già sviluppata da persone che lavorano su problemi simili e che hanno lavorato su un grande corpus di dati che dipende dal dizionario e dalla grammatica .e.g. motori di ricerca.
Non sono a conoscenza di tali apis pubblici/a pagamento, quindi il mio esempio si basa sui risultati di Google.
Proviamo a usare google:
- È possibile continuare a mettere i termini validi per Google, per passaggi multipli, e mantenere la valutazione dei risultati di un certo punteggio in base al dizionario di ricerca. qui ci sono due uscite importanti, utilizzando 2 passi del testo:
Questo outout viene utilizzato per un secondo passaggio:
che vi dà la conversione " "più recentemente lo sviluppo, che è un potente".
Per verificare la conversione, sarà necessario utilizzare un algoritmo di similarità e un punteggio per filtrare i risultati non validi/non validi.
Una tecnica grezza potrebbe utilizzare un confronto di stringhe normalizzate utilizzando difflib.
>>> import difflib
>>> import re
>>> input = "more recen t ly the develop ment, wh ich is a po ten t "
>>> output = "more recently the development, which is a potent "
>>> input_norm = re.sub(r'\W+', '', input).lower()
>>> output_norm = re.sub(r'\W+', '', output).lower()
>>> input_norm
'morerecentlythedevelopmentwhichisapotent'
>>> output_norm
'morerecentlythedevelopmentwhichisapotent'
>>> difflib.SequenceMatcher(None,input_norm,output_norm).ratio()
1.0
Ma come funziona quando le frasi possono essere organizzate in più di un ordine? "Pen is mig htier tha n sw ord" – DhruvPathak
Approccio elegante, ma scartare tutti gli spazi lo trasforma in un problema più difficile. La descrizione OPS ("rimuovere gli spazi indesiderati") suggerisce che gli spazi non mancano mai; se questo è corretto, non si dovrebbe mai guardare all'interno di un frammento per interruzioni di parole. – alexis
@alexis, hai ragione, immagino che la performance possa essere migliorata almeno di un ordine di grandezza, calcolando solo le probabilità per i vari join invece di tutte le divisioni. Probabilmente tornerò più tardi per riformulare la mia risposta. – miku