我正在编写一个文本标记解析器,我正在使用这种递归方法来创建 n 字的标记。有没有办法可以非递归地或至少优化它?假设$ this-> dataArray可能是一个非常大的数组。
/**
* A recursive function to add phrases to the tagTracker array
* @param string $data
* @param int $currentIndex
* @param int $depth
*/
protected function compilePhrase($data, $currentIndex, $depth){
if (!empty($data)){
if ($depth >= $this->phraseStart){
$this->addDataCount($data, $depth);
}
if ($depth < $this->phraseDepth){
$currentIndex = $currentIndex + 1;
//$this->dataArray is an array containing all words in the text
$data .= ' '.$this->dataArray[$currentIndex];
$depth += 1;
$this->compilePhrase($data, $currentIndex, $depth);
}
}
}
答案 0 :(得分:3)
看看您是否可以使用 tail recursion 而不是基于呼叫的递归。可能需要进行一些重写,但粗略的看起来表示这样做很好。
尾递归对于递归函数的子集非常有用,并且可以很好地发现循环何时可以替换递归,以及如何重写。
这样说,我不知道PHP内部的开销是多少。可能只是一个返回指针类型设置而不是真正的堆栈风。
事实证明是一样的。 PHP会优化尾递归调用吗?
这是我的重写,但要注意,我的大脑目前睡眠不足!
protected function compilePhrase($data, $currentIndex, $depth){
/* Loop until break condition */
while(true) {
if (!empty($data)){
if ($depth >= $this->phraseStart){
$this->addDataCount($data, $depth);
}
if ($depth < $this->phraseDepth){
$currentIndex = $currentIndex + 1;
// A test here might be better than the !empty($data)
// in the IF condition. Check array bounds, assuming
// array is not threaded or anything
$data .= ' '.$this->dataArray[$currentIndex];
$depth += 1;
}else{
break;
}
}else{
break;
}
}
/* Finish up here */
return($this->dataArray);
}