以下是N-ary树结构的一些示例代码;
class PrefixCache {
const EOS = 'eos';
protected $data;
function __construct() {
$this->data = array();
$this->data[self::EOS] = false;
}
function addPrefix($str) {
$str = (string) $str;
$len = strlen($str);
for ($i=0, $t =& $this->data; $i
$ch = $str[$i];
if (!isset($t[$ch])) {
$t[$ch] = array();
$t[$ch][self::EOS] = false;
}
$t =& $t[$ch];
}
$t[self::EOS] = true;
}
function matchPrefix($str) {
$str = (string) $str;
$len = strlen($str);
$so_far = '';
$best = '';
for ($i=0, $t =& $this->data; $i
$ch = $str[$i];
if (!isset($t[$ch]))
return $best;
else {
$so_far .= $ch;
if ($t[$ch][self::EOS])
$best = $so_far;
$t =& $t[$ch];
}
}
return false; // string not long enough - potential longer matches remain
}
function dump() {
print_r($this->data);
}
}
这可以称为
$pre = new PrefixCache();
$pre->addPrefix('304');
$pre->addPrefix('305');
// $pre->addPrefix('3056');
$pre->addPrefix('3057');
echo $pre->matchPrefix('30561234567');
根据需要执行(返回305;如果取消注释3056,则返回3056).
请注意,我为每个节点添加了一个terminal-flag;这可以避免错误的部分匹配,即如果你添加前缀3056124,它将正确匹配3056而不是返回305612.
避免每次重新加载的最佳方法是将其转换为服务;但是,在这之前我会测量APC的运行时间.它可能足够快.
亚历克斯:你的答案绝对正确 – 但不适用于这个问题:)