¿Puede un humano hacerlo?
farsidebag
far sidebag
farside bag
far side bag
No sólo usted tiene que usar un diccionario, puede que tenga que utilizar un enfoque estadístico para averiguar lo que es más probable (o, Dios no lo quiera, un HMM real de su lenguaje humano de elección ...)
para saber cómo hacer estadísticas que podrían ser útiles, que a su vez a Dr. Peter Norvig, que se dirige a un problema diferente, pero relacionado de corrección ortográfica en 21 líneas de código: http://norvig.com/spell-correct.html
(he hace trampa un poco doblando cada bucle en una sola línea ... pero aún así).
actualización Esto quedó atascado en mi cabeza, así que tuve que nacer hoy en día.Este código realiza una división similar a la descrita por Robert Gamble, pero luego ordena los resultados en función de la frecuencia de las palabras en el archivo de diccionario proporcionado (que ahora se espera que sea un texto representativo de su dominio o inglés en general. .txt de Norvig, vinculado anteriormente, y le echó un diccionario, para cubrir palabras faltantes).
Una combinación de dos palabras la mayoría de las veces superará una combinación de 3 palabras, a menos que la diferencia de frecuencia sea enorme.
he publicado este código con algunos cambios de menor importancia en mi blog
http://squarecog.wordpress.com/2008/10/19/splitting-words-joined-into-a-single-string/ y también escribió un poco sobre el error de desbordamiento en este código .. tuve la tentación de simplemente en silencio arreglarlo, pero pensó que esto puede ayudar a algunas personas que no han visto el truco de registro antes: http://squarecog.wordpress.com/2009/01/10/dealing-with-underflow-in-joint-probability-calculations/
de salida en sus palabras, además de unos cuantos de mi propia - Anuncio de lo que sucede con "orcore":
perl splitwords.pl big.txt words
answerveal: 2 possibilities
- answer veal
- answer ve al
wickedweather: 4 possibilities
- wicked weather
- wicked we at her
- wick ed weather
- wick ed we at her
liquidweather: 6 possibilities
- liquid weather
- liquid we at her
- li quid weather
- li quid we at her
- li qu id weather
- li qu id we at her
driveourtrucks: 1 possibilities
- drive our trucks
gocompact: 1 possibilities
- go compact
slimprojector: 2 possibilities
- slim projector
- slim project or
orcore: 3 possibilities
- or core
- or co re
- orc ore
Código:
#!/usr/bin/env perl
use strict;
use warnings;
sub find_matches($);
sub find_matches_rec($\@\@);
sub find_word_seq_score(@);
sub get_word_stats($);
sub print_results([email protected]);
sub Usage();
our(%DICT,$TOTAL);
{
my($dict_file, $word_file) = @ARGV;
($dict_file && $word_file) or die(Usage);
{
my $DICT;
($DICT, $TOTAL) = get_word_stats($dict_file);
%DICT = %$DICT;
}
{
open(my $WORDS, '<', $word_file) or die "unable to open $word_file\n";
foreach my $word (<$WORDS>) {
chomp $word;
my $arr = find_matches($word);
local $_;
# Schwartzian Transform
my @sorted_arr =
map { $_->[0] }
sort { $b->[1] <=> $a->[1] }
map {
[ $_, find_word_seq_score(@$_) ]
}
@$arr;
print_results($word, @sorted_arr);
}
close $WORDS;
}
}
sub find_matches($){
my($string) = @_;
my @found_parses;
my @words;
find_matches_rec($string, @words, @found_parses);
return @found_parses if wantarray;
return \@found_parses;
}
sub find_matches_rec($\@\@){
my($string, $words_sofar, $found_parses) = @_;
my $length = length $string;
unless($length){
push @$found_parses, $words_sofar;
return @$found_parses if wantarray;
return $found_parses;
}
foreach my $i (2..$length){
my $prefix = substr($string, 0, $i);
my $suffix = substr($string, $i, $length-$i);
if(exists $DICT{$prefix}){
my @words = (@$words_sofar, $prefix);
find_matches_rec($suffix, @words, @$found_parses);
}
}
return @$found_parses if wantarray;
return $found_parses;
}
## Just a simple joint probability
## assumes independence between words, which is obviously untrue
## that's why this is broken out -- feel free to add better brains
sub find_word_seq_score(@){
my(@words) = @_;
local $_;
my $score = 1;
foreach (@words){
$score = $score * $DICT{$_}/$TOTAL;
}
return $score;
}
sub get_word_stats($){
my ($filename) = @_;
open(my $DICT, '<', $filename) or die "unable to open $filename\n";
local $/= undef;
local $_;
my %dict;
my $total = 0;
while (<$DICT>){
foreach (split(/\b/, $_)) {
$dict{$_} += 1;
$total++;
}
}
close $DICT;
return (\%dict, $total);
}
sub print_results([email protected]){
#('word', [qw'test one'], [qw'test two'], ...)
my ($word, @combos) = @_;
local $_;
my $possible = scalar @combos;
print "$word: $possible possibilities\n";
foreach (@combos) {
print ' - ', join(' ', @$_), "\n";
}
print "\n";
}
sub Usage(){
return "$0 /path/to/dictionary /path/to/your_words";
}
Tenga en cuenta que una implementación ingenua devolvería "wick ed weather" –
hey soluciones óptimas, vi su respuesta en una pregunta EMR y me preguntaba si podría contactarlo con algunas preguntas sobre TI sanitaria. –