Un homme de le faire?
farsidebag
loin sidebag
la face cachée sac
côté sac
Non seulement vous avez à utiliser un dictionnaire, vous pourriez avoir à utiliser une approche statistique pour comprendre ce qui est le plus probable (ou, à dieu ne plaise, un HMM pour votre choix de langue...)
Pour savoir comment faire des statistiques qui pourraient vous être utiles, je vous tourner vers le Dr Peter Norvig, qui s'attaque à un autre, mais le problème connexe de la vérification orthographique dans 21 lignes de code:
http://norvig.com/spell-correct.html
(il ne triche un peu en pliant chaque boucle for en une seule ligne.. mais quand même).
Mise à jour de Ce est resté coincé dans ma tête, j'ai donc eu à la naissance il aujourd'hui. Ce code n'similaire split à celui décrit par Robert Pari, mais ensuite il ordonne les résultats basés sur la fréquence des mots dans le dictionnaire fichier (qui est maintenant prévu pour être certains de texte représentant de votre domaine ou de l'anglais en général. J'ai utilisé big.txt de Norvig, ci-dessus, et catted un dictionnaire, pour couvrir des mots manquants).
Une combinaison de deux mots sera la plupart du temps battre une combinaison de 3 mots, à moins que la différence de fréquence est énorme.
J'ai posté ce code avec quelques modifications mineures sur mon blog
http://squarecog.wordpress.com/2008/10/19/splitting-words-joined-into-a-single-string/
et a également écrit un peu plus sur l'underflow bug dans ce code.. j'ai été tenté de juste tranquillement le corriger, mais pensé que cela peut aider certaines personnes qui n'ont pas vu le journal de truc avant:
http://squarecog.wordpress.com/2009/01/10/dealing-with-underflow-in-joint-probability-calculations/
Sortie sur vos mots, plus un peu de mes propres -- remarquez ce qui se passe avec "orcore":
perl splitwords.pl big.txt mots
answerveal: 2 possibilités
- réponse de veau
- réponse ve al
wickedweather: 4 possibilités
- intempéries
- wicked nous à son
- mèche ed météo
- mèche ed nous à son
liquidweather: 6 possibilités
- liquide de la météo
- liquide de nous à son
- li quid de la météo
- li quid nous à son
- li qu id météo
- li qu id, nous sommes à son
driveourtrucks: 1 possibilités
nos camions
gocompact: 1 possibilités
- aller compact
slimprojector: 2 possibilités
- projecteur slim
- mince, projet ou
orcore: 3 possibilités
- ou core
- ou co re
- orc de minerai de
Code:
#!/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($@);
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($@){
#( '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";
}