Ho bisogno di trovare la stringa ripetuta più lunga nella sottostringa. Diciamo che ho stringa "bannana"
come ottenere la stringa ripetuta più lunga nella sottostringa dall'albero dei suffissi
Wikipedia says seguente:
In informatica, il problema più lunga sottostringa ripetuto è il problema di trovare la sottostringa più lunga di una stringa che si verifica in almeno due volte. Nella figura con la stringa "ATCGATCGA $", la più lunga ripetuto stringa è "ATCGA"
quindi immagino che per la stringa "bannana"
ci sono due sottostringhe altrettanto lunghi (se non mi corregga per favore): "an"
e "na"
.
Wikipedia anche says che per questo scopo vengono utilizzati gli alberi di suffisso. Per essere più precisi here è citazione come farlo (questo mi sembra più understable di definizione su wikipedia):
costruire un albero suffisso, quindi trovare il nodo più alto con almeno 2 discendenti.
Ho trovato diverse implementazioni di alberi di suffisso. Codice seguente è tratto da here:
use strict;
use warnings;
use Data::Dumper;
sub classify {
my ($f, $h) = (shift, {});
for (@_) { push @{$h->{$f->($_)}}, $_ }
return $h;
}
sub suffixes {
my $str = shift;
map { substr $str, $_ } 0 .. length($str) - 1;
}
sub suffix_tree {
return +{} if @_ == 0;
return +{ $_[0] => +{} } if @_ == 1;
my $h = {};
my $classif = classify sub { substr shift, 0, 1 }, @_;
for my $key (sort keys %$classif) {
my $subtree = suffix_tree(
grep "$_", map { substr $_, 1 } @{$classif->{$key}}
);
my @subkeys = keys %$subtree;
if (@subkeys == 1) {
my $subkey = shift @subkeys;
$h->{"$key$subkey"} = $subtree->{$subkey};
} else { $h->{$key} = $subtree }
}
return $h;
}
print +Dumper suffix_tree suffixes 'bannana$';
per la stringa "bannana"
restituisce seguente albero:
$VAR1 = {
'$' => {},
'n' => {
'a' => {
'na$' => {},
'$' => {}
},
'nana$' => {}
},
'a' => {
'$' => {},
'n' => {
'a$' => {},
'nana$' => {}
}
},
'bannana$' => {}
};
Un'altra implementazione è online da here, per la stringa "bannana"
restituisce seguente albero:
7: a
5: ana
2: annana
1: bannana
6: na
4: nana
3: nnana
|(1:bannana)|leaf
tree:|
| |(4:nana)|leaf
|(2:an)|
| |(7:a)|leaf
|
| |(4:nana)|leaf
|(3:n)|
| |(5:ana)|leaf
3 branching nodes
Domande:
- Come posso ottenere da quei grafici
"an"
e"na"
stringhe? - Come puoi vedere gli alberi sono diversi, sono equivalenti o meno, se sì perché sono diversi, se non quale algoritmo è corretto?
- Se l'implementazione di perl è errata esiste un'implementazione funzionante per perl/python?
- Ho letto sull'algoritmo di Ukkonen che è anche menzionato a pagina con il 2o esempio (non ho capito se la versione online sta usando questo algoritmo o no), qualcuno degli esempi citati usa questo algoritmo? In caso contrario, l'algoritmo utilizzato è più lento o presenta qualche svantaggio rispetto a Ukkonen?
Non è abbastanza chiaro come la prima implementazione sia riuscita a convertire 'bannana' in' banana'. –
La prima implementazione è dubbia: è 'bannana' o' banana'? La seconda sembra sbagliata: ha 5 foglie, ma 'bannana' ha 7 lettere, quindi dovrebbe avere 7 foglie, secondo la definizione. – IVlad
Anche la notazione è confusa. Gli alberi suffissi di solito etichettano i bordi, non i nodi. Ma tu sembri etichettare i nodi, quindi cosa rappresentano le tue etichette? – IVlad