trie php,php-优化Trie实现

除了乐趣之外,我今天没有实现Trie.目前它支持add()和search(),remove()也应实现,但我认为这很简单.

它具有完整的功能,但是按照我的喜好,用数据填充Trie会花费太多.我使用此列表作为数据源:http://www.isc.ro/lists/twl06.zip(在SO上的其他地方找到).加载大约需要11秒.我最初的实现花费了大约15秒,所以我已经给它带来了不错的性能提升,但是我仍然不满意:)

我的问题是:还有什么可以使我获得(实质性的)性能提升?我不受此设计的束缚,可以接受全面的大修.

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;

}

}

解决方法:

不知道php,但是,

通过以下方法:

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;

}

为什么甚至需要$str.= $char(我想是追加)?这本身会将您的O(n)时间加法/搜索更改为Omega(n ^ 2)(n是$value的长度),而不是O(n).

在特里树中,通常会在遍历字符串时遍历树头,即根据当前字符而不是当前前缀找到下一个节点.

标签:trie,data-structures,optimization,php

来源: https://codeday.me/bug/20191106/1998864.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值