Pour la seule raison que ce soit amusant, j'ai implémenté un Trie aujourd'hui. Pour le moment, il supporte add() et search(), remove() devrait aussi être implémenté mais je pense que c'est assez simple.Optimisation de l'implémentation de Trie
Il est entièrement fonctionnel, mais remplir le Trie avec des données prend un peu trop à mon goût. J'utilise cette liste comme source de données: http://www.isc.ro/lists/twl06.zip (trouvé ailleurs sur SO). Cela prend ~ 11s à charger. Ma mise en œuvre initiale a pris ~ 15s donc je lui ai déjà donné une belle amélioration de la performance, mais je ne suis toujours pas satisfait :)
Ma question est: quoi d'autre pourrait me donner un coup de pouce (substantiel) de performance? Je ne suis pas lié par cette conception, une révision complète est acceptable.
class Trie
{
private $trie;
public function __construct(TrieNode $trie = null)
{
if($trie !== null) $this->trie = $trie;
else $this->trie = new TrieNode();
$this->counter = 0;
}
public function add($value, $val = null)
{
$str = '';
$trie_ref = $this->trie;
foreach(str_split($value) as $char)
{
$str .= $char;
$trie_ref = $trie_ref->addNode($str);
}
$trie_ref->value = $val;
return true;
}
public function search($value, $only_words = false)
{
if($value === '') return $this->trie;
$trie_ref = $this->trie;
$str = '';
foreach(str_split($value) as $char)
{
$str .= $char;
if($trie_ref = $trie_ref->getNode($str))
{
if($str === $value) return ($only_words ? $this->extractWords($trie_ref) : new self($trie_ref));
continue;
}
return false;
}
return false;
}
public function extractWords(TrieNode $trie)
{
$res = array();
foreach($trie->getChildren() as $child)
{
if($child->value !== null) $res[] = $child->value;
if($child->hasChildren()) $res = array_merge($res, $this->extractWords($child));
}
return $res;
}
}
class TrieNode
{
public $value;
protected $children = array();
public function addNode($index)
{
if(isset($this->children[$index])) return $this->children[$index];
return $this->children[$index] = new self();
}
public function getNode($index)
{
return (isset($this->children[$index]) ? $this->children[$index] : false);
}
public function getChildren()
{
return $this->children;
}
public function hasChildren()
{
return count($this->children)>0;
}
}
Avez-vous déjà le code à l'aide PROFILES [xhprof] (http://pecl.php.net/package/xhprof) ou [xdebug] (http: // PECL .php.net/paquet/xdebug)? – Charles
je n'ai pas encore, bon appel. Je vais demain! –